(自己编写且已通过,留来后面优化,不断更新中ing)
class Solution {
public:
// Parameters:
// numbers: an array of integers
// length: the length of array numbers
// duplication: (Output) the duplicated number in the array number
// Return value: true if the input is valid, and there are some duplications in the array number
// otherwise false
bool duplicate(int numbers[], int length, int* duplication)
{
int i=0,temp=0,num=0;
for(i=0;i
class Solution {
public:
bool Find(int target, vector > array) {
int m=array[0].size();//输入数组列数
int n=array.size();//输入数组行数
int i=0,j=m-1;//初始行列位置,矩阵右上角
if(m==0||n==0)
return false;
while(1)
{
if((i>n-1)||(j<0))//判断是否超出边界
{
return false;
}
if(array[i][j]==target)//比较当前数字和目标数字
return true;
else if(array[i][j]
5.请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
class Solution {
public:
void replaceSpace(char *str,int length)
{
int spacenum=0;
int strlength=0;
if(str==NULL||length<=0)return;
while(*str!='\0')//获取空格数
{
if(*str==' ')
spacenum++;
str++;
strlength++;
}
int newstrlength=strlength+2*spacenum;//获取新字符串长度
if(newstrlength>length)
return;
int p1=strlength-1;
int p2=newstrlength-1;
while(spacenum!=0)//从原字符串末尾处往新字符串末尾拷贝
{
if(*(str+p1)==' ')
{
*(str+(p2--))='0';
*(str+(p2--))='2';
*(str+p2)='%';
p2--;
spacenum--;
}
else{
*(str+p2--)=*(str+p1);
}
p1--;
}
}
};
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector printListFromTailToHead(ListNode* head) {
vector res;
if(head==nullptr)
return res;
ListNode* pnode=head;
while(pnode!=nullptr)
{
res.push_back(pnode->val);
pnode=pnode->next;
}
reverse(res.begin(), res.end());
return res;
}
};
方法2(翻转链表):
class Solution {
public:
vector printListFromTailToHead(ListNode* head) {
vector ivec;
if(head == NULL || head->next == NULL)
{
return ivec;
}
ListNode* phead=(ListNode*)malloc(sizeof(ListNode));
phead->val=0;
phead->next=head;
//反转
ListNode* prev = NULL;
ListNode* cur = phead->next;
ListNode* next = NULL;
while(cur)
{
next = cur->next;
cur->next = prev;
prev = cur;
cur = next;
}
phead->next = prev;
//赋值
ListNode *p = phead->next;
while(p)
{
ivec.push_back(p->val);
p = p->next;
}
return ivec;
}
};
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
struct TreeNode* reConstructBinaryTree(vector pre,vector in) {
int inlen=in.size();
if(inlen==0)//判别结束条件
return NULL;
vector left_pre,right_pre,left_in,right_in;
//创建根节点,根节点肯定是前序遍历的第一个数
TreeNode* head=new TreeNode(pre[0]);
//找到中序遍历根节点所在位置,存放于变量gen中
int gen=0;
for(int i=0;ileft=reConstructBinaryTree(left_pre,left_in);
head->right=reConstructBinaryTree(right_pre,right_in);
return head;
}
};
class Solution {
public:
TreeLinkNode* GetNext(TreeLinkNode* pNode)
{
if(pNode==NULL)
return NULL;
if(pNode->right!=NULL)
{
pNode=pNode->right;
while(pNode->left!=NULL)
pNode=pNode->left;
return pNode;
}
while(pNode->next!=NULL)
{
TreeLinkNode *proot=pNode->next;
if(proot->left==pNode)
return proot;
pNode=pNode->next;
}
return NULL;
}
};
class Solution
{
public:
void push(int node) {
while(stack2.empty()!=true){
stack1.push(stack2.top());
stack2.pop();
}
stack1.push(node);
}
int pop() {
int popnum=0;
while(stack1.empty()!=true){
stack2.push(stack1.top());
stack1.pop();
}
popnum=stack2.top();
stack2.pop();
return popnum;
}
private:
stack stack1;
stack stack2;
};
上面解法繁琐了<分析>:
入栈:将元素进队列A
出栈:判断队列A中元素的个数是否为1,如果等于1,则出队列,否则将队列A中的元素 以此出队列并放入队列B,直到队列A中的元素留下一个,然后队列A出队列,再把 队列B中的元素出队列以此放入队列A中。正解如下:
class Solution
{
public:
void push(int node) {
stack1.push(node);
}
int pop() {
int a;
if(stack2.empty()){
while(!stack1.empty()){
a=stack1.top();
stack2.push(a);
stack1.pop();
}
}
a=stack2.top();
stack2.pop();
return a;
}
private:
stack stack1;
stack stack2;
};
class Solution {
public:
int minNumberInRotateArray(vector rotateArray) {
int vsize=rotateArray.size();
if(vsize==1)return rotateArray[0];
if(rotateArray[0]<=rotateArray[vsize-1]&&rotateArray[0]<=rotateArray[1])
return rotateArray[0];
int L=0,R=vsize-1,M=0;
while(L!=(R-1))
{
M=(R+L)/2;
if(rotateArray[M]<=rotateArray[R])
R=M;
else
L=M;
}
if(rotateArray[L]>rotateArray[R])
return rotateArray[R];
else
return rotateArray[L];
}
};
正解:
#include
#include
#include
#include
#include
using namespace std;
class Solution {
public:
int minNumberInRotateArray(vector rotateArray) {
int size = rotateArray.size();
if(size == 0){
return 0;
}//if
int left = 0,right = size - 1;
int mid = 0;
// rotateArray[left] >= rotateArray[right] 确保旋转
while(rotateArray[left] >= rotateArray[right]){
// 分界点
if(right - left == 1){
mid = right;
break;
}//if
mid = left + (right - left) / 2;
// rotateArray[left] rotateArray[right] rotateArray[mid]三者相等
// 无法确定中间元素是属于前面还是后面的递增子数组
// 只能顺序查找
if(rotateArray[left] == rotateArray[right] && rotateArray[left] == rotateArray[mid]){
return MinOrder(rotateArray,left,right);
}//if
// 中间元素位于前面的递增子数组
// 此时最小元素位于中间元素的后面
if(rotateArray[mid] >= rotateArray[left]){
left = mid;
}//if
// 中间元素位于后面的递增子数组
// 此时最小元素位于中间元素的前面
else{
right = mid;
}//else
}//while
return rotateArray[mid];
}
private:
// 顺序寻找最小值
int MinOrder(vector &num,int left,int right){
int result = num[left];
for(int i = left + 1;i < right;++i){
if(num[i] < result){
result = num[i];
}//if
}//for
return result;
}
};
面试题12:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
思路:这个题其实理解了就觉得不难,只是写代码可能会遇到一些问题。程序我就参考的剑指offer的例程了,程序大概流程为
1.检查边界值和初始化
2.用两层for循环从二维矩阵中每个元素开始尝试路径
3.进入一个格子,判断当前格子是否满足路径条件,如果满足则做好标记并递归判断其周围格子是否满足路径条件;否则返回上一层。
4.结束条件是当进入某一个格子后发现路径已经到str的末尾’\0’。
class Solution {
public:
bool hasPath(char* matrix, int rows, int cols, char* str)
{
if(matrixnullptr||rows<1||cols<1||strnullptr)//检查输入矩阵是否合法
return false;
bool visited=new bool[rowscols];//是否占用标志矩阵
memset(visited,0,rowscols);
int pathLength=0;
for(int row=0;row
for(int col=0;col
if(hasPathCore(matrix,rows,cols,row,col,str,pathLength,visited))
{
return true;
}
}
}
delete[] visited;
return false;
}
private:
bool hasPathCore(const char
{
if(str[pathLength]==’\0’)//结束条件
return true;
bool hasPath=false;
if(row>=0&&row
{
++pathLength;
visited[row* cols+col]=true;//满足条件则标记为true
hasPath=hasPathCore(matrix,rows,cols,row,col-1,str,pathLength,visited)||//递归地遍历上下左右的格子
hasPathCore(matrix,rows,cols,row-1,col,str,pathLength,visited)||
hasPathCore(matrix,rows,cols,row,col+1,str,pathLength,visited)||
hasPathCore(matrix,rows,cols,row+1,col,str,pathLength,visited);
if(!hasPath)//判断周围的格子是否存在路径
{
–pathLength;//没有合适的路径返回上一层
visited[row*cols+col]=false;
}
}
return hasPath;
}
}; class Solution { private: }; 高级解法: 面试题16:给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。 牛客网上的大神解法: 面试题17:打印从1到最大的n位数
面试题13:地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
思路:思路和矩阵中找字符串相似,也是采用递归遍历的方法,其实还比上一题简单一些,自己做了一遍发现始终找到的格子比答案少几个,最后终于发现是rcSum
(1) 若满足条件,做好标记,并递归遍历周围的格子,返回可进入的格子数。
(2) 不满足则返回0,退回上一层。
(3) 结束条件是当周围没有可进入的格子(已标记的格子也不能再进入)。
public:
int movingCount(int threshold, int rows, int cols)
{
int num=0;
if(threshold<0||rows<1||cols<1)
return 0;
bool visited=new bool[rows * cols];
memset(visited,0,rowscols);
num=Counter(threshold,rows,cols,0,0,visited);
delete [] visited;
return num;}
int Counter(int threshold,int rows, int cols, int row, int col,bool visited)
{
int num = 0;
if(checkout(threshold,rows,cols,row,col,visited))//判断当前格子是否可进
{
visited[rowcols+col]=true;
num=1+Counter(threshold,rows,cols,row+1,col,visited)+Counter(threshold,rows,cols,row-1,col,visited)+
Counter(threshold,rows,cols,row,col-1,visited)+Counter(threshold,rows,cols,row,col+1,visited);
}
return num;
}
bool checkout(int threshold,int rows, int cols,int row, int col,bool visited)
{
if(visited[rowcols+col]!=true&&row>=0&&row
int rcSum=0;
while(row>0)//取行列的每一位,并求和
{
rcSum+=row%10;
row=row/10;
}
while(col>0)
{
rcSum+=col%10;
col=col/10;
}
if(rcSum<=threshold)//判断能否进入以及是否已被访问
return true;
}
return false;}
面试题15:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
这个题看似简单,但其实做题时你会发现,如果对二进制不是太熟悉,做起来还是不简单。
常规解法:
把n和1做与运算,再判断该位是否为1,接着将1左移1位得到2,再判断该位是否为1,然后一直左移直到整数二进制的最左边,也就是,循环的次数为整数二进制的位数。class Solution {
public:
int NumberOf1(int n) {
int count = 0;
unsigned int flag = 1;
while(flag)
{
if(n&flag)count++;
flag=flag<<1;
}
return count;
}
};
把一个整数减去1,再和原来的整数相与,可将原整数最左边的1变为0,一个二进制整数中有多少个1,就能进行多少次这样的操作。class Solution {
public:
int NumberOf1(int n) {
int count = 0;
while(n)
{
++count;
n=(n-1)&n;
}
return count;
}
};
解题思路:这道题看似简单,但做对却需要考虑好各种情况,我的思路是考虑底数为0,不为0;指数为0、为整数、负数这几种情况,然后每种情况一一处理。class Solution {
public:
double Power(double base, int exponent) {
if(exponent==0)return 1;
if(base==0)return 0;//如果同时为0无意义
double result=1;
if(exponent>0)
{
for(int i=0;i
这里关键在于用移位代替除2,用位与运算代替了求余来判断最后一个数是奇数还是偶数,将运算效率提高。class Solution {
public:
double Power(double base, int exponent) {
double res = 1,curr = base;
int tempexponent;
if(exponent>0){
tempexponent = exponent;
}else if(exponent<0){
if(base==0)
return 0;//分母为0的情况
tempexponent = -exponent;
}else{// exponent==0
return 1;// 0的0次方
}
while(tempexponent!=0){
if((tempexponent&1)==1)
res*=curr;
curr*=curr;// 翻倍
tempexponent>>=1;// 右移一位
}
return exponent>=0?res:(1/res);
}
};
题目:输入数字n,按顺序打印出从1到最大的n位十进制数,比如输入3,则打印出1、2、3一直到最大的三位数999. int main() {
int base = 0, exponent = 0,res=0;
while (1)
{
cout << "plese input the length of the num:" << endl;
cin >> base;
Print1toN(base);
}
}
void Print1toN(int n)
{
if (n <= 0)
return;
char* number = new char[n + 1];//定义n+1个长度,因为最后一个为'\0'
memset(number,'0',n);//全置'0'
number[n] = '\0';
while (!Increment(number))//增加数字并判断是否满足结束条件
{
PrintNumber(number);//打印数字
}
delete[]number;
}
bool Increment(char *number)
{
bool isOverflow = false;
int nTakeOver = 0;//进位
int nLength = strlen(number);
for (int i=nLength-1;i>=0;i--)
{
int nSum = number[i] - '0' + nTakeOver;//第n-i位的值
if (i == nLength - 1)
nSum++;
if (nSum >= 10)//产生进位
{
if (i == 0)//如果最高位为0,则结束打印
isOverflow = true;
else
{
nSum -= 10;
nTakeOver = 1;
number[i] = '0' + nSum;
}
}
else
{
number[i] = '0' + nSum;
break;
}
}
return isOverflow;
}
void PrintNumber(char *number)
{
bool isBeginning0 = true;
int nLength = strlen(number);
for (int i=0;i