在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字是重
复的,也不知道每个数字重复几次。请找出数组中任意一个重复的数字。
思路:
数组大小为n,数字范围为0~n-1,也就是说如果数组不重复,则排序后每个数组i上的元素就应该是i
为此,我们可以模拟这个排序的过程,如果i位置上的元素不为i,则把它与nums[i]位置的元素进行交换,这相当于把nums[i]放到他该去的地方。如果nums[i]位置的元素已经是i了,则这刚好就是重复的数字;否则将交换到i位置上的数字继续这个过程,如果交换过来的数等于i,则说明这个数放在了他应该放的地方,继续处理i+1上的数,如果仍然不等,则将这个换来的数放到他应该放的地方....最后,对于i位置来说,要么找到了值为i的元素,要么找到了重复的元素,是不可能出现无限循环的,因为无限循环要求换来的数字与i位置的数字相等,但这时候已经判定重复并跳出返回了。
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) { if(length<=1) return false; int p1=0; while(p1<length) { if(numbers[p1]!=p1) { while(numbers[p1]!=p1) { int right=numbers[numbers[p1]]; if(numbers[p1]==right) { *duplication=right; return true; } swap(numbers[numbers[p1]],numbers[p1]); } } p1++; } return false; } void swap(int& a,int& b) { int tmp=a; a=b; b=tmp; } };
class Solution { public: bool Find(int target, vector<vector<int> > array) { auto& nums=array; if(nums.empty()||nums[0].empty()) return false; int row=nums.size()-1; int col=0; while(row>=0&&col<nums[row].size()) { if(nums[row][col]==target) return true; else if(nums[row][col]<target) col++; else row--; } return false; } };
int pLast=len+count*2;
int pCur=len;
而不是
int pLast=len+count*2-1;
int pCur=len-1;
虽然这一种也能实现,但少了个‘\0‘,需要自己在补一个。
class Solution { public: void replaceSpace(char *str,int length) { int len=length; int count=0; for(int i=0;i<len;i++) { if(str[i]==‘ ‘) count++; } int pLast=len+count*2; int pCur=len; while(pCur>=0&&pLast>pCur) { if(str[pCur]!=‘ ‘) { str[pLast]=str[pCur]; pLast--; } else { str[pLast--]=‘0‘; str[pLast--]=‘2‘; str[pLast--]=‘%‘; } pCur--; } return ; } };
class Solution { public: vector<int> printListFromTailToHead(ListNode* head) { vector<int> ans; if(!head) return ans; Core(ans,head); return ans; } void Core(vector<int>& in,ListNode* head) { if(!head) return; Core(in,head->next); in.push_back(head->val); } };
思路很清晰的题,但容易出错,多写几次注意下细节,特别是传参长度的处理。
class Solution { public: TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) { if(pre.empty()||pre.size()!=vin.size()) return NULL; return reConstructCore(pre,vin,0,0,pre.size()); } TreeNode* reConstructCore(vector<int>& pre,vector<int>& vin,int pstart,int vstart,int len) { if(len<=0) return NULL; int tmp=pre[pstart]; int pos=0; for(;pos<len&&vin[pos+vstart]!=tmp;pos++); pos+=vstart; int left=pos-vstart; int right=len-left-1; TreeNode* root=new TreeNode(tmp); root->left=reConstructCore(pre,vin,pstart+1,vstart,left); root->right=reConstructCore(pre,vin,pstart+left+1,pos+1,right); return root; } };
要考虑的情况很多,值得好好看看,体味下二叉树的结构
class Solution { public: TreeLinkNode* GetNext(TreeLinkNode* pNode) { if(!pNode) return NULL; return GetNextCore(pNode); } TreeLinkNode* GetNextCore(TreeLinkNode* node) { if(!node->next) { auto it=node->right; if(!it) return NULL; while(it->left) it=it->left; return it; } auto pLast=node->next; if(pLast->left==node) { if(node->right) { auto right=node->right; while(right->left) right=right->left; return right; } else return pLast; } else if(pLast->right==node) { if(node->right) { auto right=node->right; while(right->left) right=right->left; return right; } else { while(pLast->next&&pLast->next->right==pLast) pLast=pLast->next; if(pLast->next==NULL) return NULL; else return pLast->next; } } else return NULL; } };
这个分类讨论太多了,其实完全可以简化:
1).如果该节点存在右子树,则应该遍历右子树中的最左节点
2).如果不存在,则要找到某个节点,该节点是其父的左子节点(包括目前的这个节点)
这样就简化很多了
class Solution { public: TreeLinkNode* GetNext(TreeLinkNode* pNode) { if(!pNode) return NULL; auto right=pNode->right; if(right) { while(right->left) right=right->left; return right; } else { while(pNode->next&&pNode->next->right==pNode) pNode=pNode->next; if(pNode->next) return pNode->next; else return NULL; } } };
思路:
栈的特点是先入后出,队列的特点是先入先出
现在给了两个栈,其实可以想象成这样一个情景:
Tail和Head相当于两个水管,水从tail中流入,从Head中流出,这样实际上就相当于实现了队列
我们在Tail中灌水,就相当于push进数,然后pop提出最先灌进去的数,则从Head中读出。
如果Head现在是空,也就是说没有元素,则把Tail里的数全部转到Head中,当然顺序要变化,这也就相当于上图里用个管子把两个容器相连,然后把Tail底部的水抽到Head中
每次push都push到Tail中。
class Solution { public: void push(int node) { stack2.push(node); } int pop() { if(!stack1.empty()) { auto ans=stack1.top(); stack1.pop(); return ans; } else { if(stack2.empty()) return INT_MIN; while(!stack2.empty()) { stack1.push(stack2.top()); stack2.pop(); } auto ans=stack1.top(); stack1.pop(); return ans; } } private: stack<int> stack1;//head stack<int> stack2;//tail };
原文:https://www.cnblogs.com/lxy-xf/p/11516404.html