剑指offer(1)
数组:二位数组中的查找
题目描述:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
1 class Solution { 2 public: 3 bool Find(vector<vector<int> > array,int target) { 4 //从右上角开始找 5 /*int row=0; 6 int column = array[0].size()-1; 7 while(row<array.size() && column>=0) 8 { 9 int num = array[row][column]; 10 if(target ==num) 11 return true; 12 else if(target > num) 13 row++; 14 else 15 column--; 16 } 17 return false;*/ 18 //从左下角开始找 19 /*int row = array.size()-1; 20 int col = 0; 21 while(row>=0 && col<array[0].size()) 22 { 23 int num = array[row][col]; 24 if(target == num) 25 return true; 26 else if(target > num) 27 col++; 28 else 29 row--; 30 } 31 return false;*/ 32 //利用二分找,在每一行中利用二分查找 33 for(int i=0;i<array.size();i++) 34 { 35 int low = 0; 36 int high = array[0].size()-1; 37 int mid; 38 while(low<=high) 39 { 40 mid = low+(high-low)/2; 41 int num = array[i][mid]; 42 if(num == target) 43 return true; 44 else if(target>num) 45 low = mid+1; 46 else 47 high = mid-1; 48 } 49 } 50 return false; 51 } 52 };
代码的完整性
数值的整数次方
题目描述:给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
class Solution { public: double Power(double base, int exponent) { if(exponent == 0)//指数为0值为1,0的0次方为1 return 1; if(base == 0)//底数为0均为0 return 0; double sum = 1; int n = (exponent>0)? exponent:-exponent;//要考虑底数为负,值为小数的情况 while(n--) { sum *= base; } return (exponent>0)? sum:(1/sum); } };
调整数组顺序使奇数位于偶数前面
题目描述:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
class Solution { public: void reOrderArray(vector<int> &array) { if(array.size() == 0 || array.size() == 1) return; //第一种:用空间换时间 /* vector<int> arr; for(int i=0;i<array.size();i++) { if(array[i]%2 == 1) arr.push_back(array[i]); } for(int i=0;i<array.size();i++) { if(array[i]%2 == 0) arr.push_back(array[i]); } for(int i=0;i<array.size();i++) { array[i] = arr[i]; }*/ //第二种,找到一个奇数就向它的前面去找偶数进行替换,注意相对位置不能变 //因为是从开始往后依次找奇数的,所以当前找的奇数的前面的偶数都在它与前一个奇数之间 int i,j; for(i=0;i<array.size();i++) { if(array[i]%2 == 1) { int temp = array[i]; j=i-1; while(j>=0&&array[j]%2==0){ array[j+1]=array[j]; j--; } array[j+1]=temp; } } } };
代码的鲁棒性
链表中倒数第k个结点
题目描述:输入一个链表,输出该链表中倒数第k个结点。
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { //第一种就是两个指针,相差k个距离,一起向后走,直到最后 if(pListHead == NULL || k <= 0) return NULL; /*ListNode *p = pListHead; ListNode *q = pListHead; int i=0; //走到第k个 for(;i<k&&q!=NULL;i++){ q = q->next; } if(i<k)//判断链是不是没有k个数 return NULL; while(q != NULL){ p = p->next; q = q->next; } return p;*/ //通过对整体计数,查看是否不小于k,小于则返回空,否则就从头开始走count-k步 int count = 0; ListNode *p = pListHead; while(p!=NULL){ p = p->next; count++; } if(count < k) return NULL; int n = count - k; p = pListHead; while(n--){ p = p->next; } return p; } };
反转链表
题目描述:输入一个链表,反转链表后,输出链表的所有元素。
1 /* 2 struct ListNode { 3 int val; 4 struct ListNode *next; 5 ListNode(int x) : 6 val(x), next(NULL) { 7 } 8 };*/ 9 class Solution { 10 public: 11 ListNode* ReverseList(ListNode* pHead) { 12 if(pHead==NULL || pHead->next == NULL) 13 return pHead; 14 ListNode* p = pHead; 15 ListNode* q = pHead->next; 16 p->next = NULL;//注意要头指针的next赋值为空 17 ListNode* w = NULL; 18 while(q) 19 { 20 w = q->next; 21 q->next = p; 22 p = q; 23 q = w; 24 } 25 return p; 26 } 27 };
合并两个链表
题目描述:输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
1 struct ListNode { 2 int val; 3 struct ListNode *next; 4 ListNode(int x) : 5 val(x), next(NULL) { 6 } 7 }; 8 //非递归版本 9 class Solution { 10 public: 11 ListNode* Merge(ListNode* pHead1, ListNode* pHead2) 12 { 13 if(pHead1 == NULL ) 14 return pHead2; 15 else if(pHead2 == NULL) 16 return pHead1; 17 ListNode* pHead=NULL; 18 ListNode* p=NULL; 19 if(pHead1->val <= pHead2->val) 20 { 21 pHead = pHead1; 22 pHead1 = pHead1->next; 23 } 24 else 25 { 26 pHead = pHead2; 27 pHead2 = pHead2->next; 28 } 29 p = pHead; 30 while(pHead1!=NULL && pHead2!=NULL) 31 { 32 if(pHead1->val <= pHead2->val) 33 { 34 p->next = pHead1; 35 p = p->next; 36 pHead1 = pHead1->next; 37 } 38 else 39 { 40 p->next = pHead2; 41 p = p->next; 42 pHead2 = pHead2->next; 43 } 44 } 45 if(pHead1 != NULL) 46 p->next = pHead1; 47 if(pHead2 != NULL) 48 p->next = pHead2; 49 return pHead; 50 } 51 }; 52 53 //递归版本 54 ListNode* Merge(ListNode* pHead1, ListNode* pHead2) 55 { 56 if(pHead1 == NULL ) 57 return pHead2; 58 else if(pHead2 == NULL) 59 return pHead1; 60 ListNode* pHead=NULL; 61 if(pHead1->val <= pHead2->val) 62 { 63 pHead = pHead1; 64 pHead1 = pHead1->next; 65 pHead->next = Merge(pHead1,pHead2); 66 } 67 else 68 { 69 pHead = pHead2; 70 pHead2 = pHead2->next; 71 pHead->next = Merge(pHead1,pHead2); 72 } 73 return pHead; 74 }
树的子结构
题目描述:输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)
1 struct TreeNode { 2 int val; 3 struct TreeNode *left; 4 struct TreeNode *right; 5 TreeNode(int x) : 6 val(x), left(NULL), right(NULL) { 7 } 8 }; 9 //看了别人的写的,没想到用||和&&来判断 10 class Solution { 11 public: 12 bool HasSubtree(TreeNode* pRoot1, TreeNode* pRoot2) 13 { 14 if(pRoot1 == NULL ||pRoot2 == NULL) 15 return false; 16 return Subtree(pRoot1,pRoot2) || HasSubtree(pRoot1->left,pRoot2) || HasSubtree(pRoot1->right,pRoot2); 17 } 18 bool Subtree(TreeNode* pRoot1, TreeNode* pRoot2) 19 { 20 if(pRoot2 == NULL) 21 return true; 22 if(pRoot1 == NULL) 23 return false; 24 if(pRoot1->val == pRoot2->val) 25 return Subtree(pRoot1->left,pRoot2->left) && Subtree(pRoot1->right,pRoot2->right); 26 else 27 return false; 28 } 29 };
面试思路:二叉树的镜像
题目描述:操作给定的二叉树,将其变换为源二叉树的镜像。
输入描述:
二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ / \ 11 9 7 5
1 struct TreeNode { 2 int val; 3 struct TreeNode *left; 4 struct TreeNode *right; 5 TreeNode(int x) : 6 val(x), left(NULL), right(NULL) { 7 } 8 }; 9 class Solution { 10 public: 11 void Mirror(TreeNode *pRoot) { 12 if(pRoot == NULL) 13 return; 14 //递归 15 /*if(pRoot->left!=NULL || pRoot->right!=NULL) 16 { 17 TreeNode* temp = pRoot->left; 18 pRoot->left = pRoot->right; 19 pRoot->right = temp; 20 Mirror(pRoot->left); 21 Mirror(pRoot->right); 22 }*/ 23 //非递归 24 stack<TreeNode*> st; 25 st.push(pRoot); 26 while(!st.empty()) 27 { 28 TreeNode* node = st.top(); 29 st.pop(); 30 if(node->left!=NULL || node->right!=NULL) 31 { 32 TreeNode* temp = node->left; 33 node->left = node->right; 34 node->right = temp; 35 } 36 if(node->left) 37 st.push(node->left); 38 if(node->right) 39 st.push(node->right); 40 } 41 } 42 };
画图让抽象形象化:顺时针打印矩阵
题目描述:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则依次打印出数字1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10.
1 class Solution { 2 public: 3 vector<int> printMatrix(vector<vector<int> > matrix) { 4 vector<int> res; 5 int row = matrix.size(); 6 int col = matrix[0].size(); 7 8 if(row==0 || col==0) 9 return res; 10 /*int left=0,right=col-1,top=0,bottom=row-1; 11 while(left<=right &&top<=bottom) 12 { 13 for(int i=left;i<=right;i++) 14 res.push_back(matrix[top][i]); 15 for(int i=top+1;i<=bottom;i++) 16 res.push_back(matrix[i][right]); 17 if(top!=bottom)//防止横向重复 18 for(int i=right-1;i>=left;i--) 19 res.push_back(matrix[bottom][i]); 20 if(left!=right)//防止纵向重复 21 for(int i=bottom-1;i>top;i--) 22 res.push_back(matrix[i][left]); 23 left++; 24 right--; 25 top++; 26 bottom--; 27 }*/ 28 int circle = ((row<col?row:col)-1)/2+1;//圈数 29 for(int i=0;i<circle;i++) 30 { 31 for(int j=i;j<=col-1-i;j++) 32 res.push_back(matrix[i][j]); 33 for(int k=i+1;k<=row-1-i;k++) 34 res.push_back(matrix[k][col-1-i]); 35 for(int l=col-1-i-1;l>=i && i!=row-1-i;l--)//注意判断的时候一定不要判断错重复的条件 36 res.push_back(matrix[row-1-i][l]); 37 for(int m=row-1-i-1;m>i && i!=col-1-i;m--) 38 res.push_back(matrix[m][i]); 39 } 40 return res; 41 } 42 };
举例让抽象具体化:包含min函数的栈
题目描述:定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。
1 class Solution { 2 public: 3 //使用两个stack,是为了使当pop出一个数值的时候,min中的top依旧是当前数据中的最小值 4 //每次push的时候都会将当前的最小值push进min中 5 void push(int value) { 6 data.push(value); 7 if(mindata.empty()) 8 mindata.push(value); 9 else 10 { 11 int val = mindata.top(); 12 val<=value?mindata.push(val):mindata.push(value); 13 } 14 15 } 16 void pop() { 17 data.pop(); 18 mindata.pop(); 19 } 20 int top() { 21 return data.top();//记得写return 22 } 23 int min() { 24 return mindata.top(); 25 } 26 private: 27 stack<int> data; 28 stack<int> mindata; 29 };