輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否爲該棧的彈出順序。假設壓入棧的所有數字均不相等。例如序列1,2,3,4,5是某棧的壓入順序,序列4,5,3,2,1是該壓棧序列對應的一個彈出序列,但4,3,5,1,2就不可能是該壓棧序列的彈出序列。
class Solution { public: bool IsPopOrder(vector<int> pushV,vector<int> popV) { if(pushV.size()==0||popV.size()==0) return false; stack<int> stack; int push_index=0; int pop_index=0; while(pop_index<(int )pushV.size()){ if(popV[pop_index]==pushV[push_index]){ push_index++; pop_index++; } else if(stack.size()!=0&&popV[pop_index]==stack.top()){ stack.pop(); pop_index++; } else stack.push(pushV[push_index++]); } if(stack.empty()) return true; return false; } };
/* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } };*/ class Solution { public: vector<int> PrintFromTopToBottom(TreeNode *root) { queue<TreeNode*> que; vector<int> node; if(root!=NULL) que.push(root); while(!que.empty()){ TreeNode* tmp=que.front(); que.pop(); if(tmp->left){ que.push(tmp->left); } if(tmp->right){ que.push(tmp->right); } node.push_back(tmp->val); } return node; } };
//左子樹一定比右子樹小,因此去掉根後,數字分爲left,right兩部分,right部分的
//最後一個數字是右子樹的根他也比左子樹所有值大,因此我們可以每次只看有子樹是否符合條件
//即可,即使到達了左子樹左子樹也可以看出由左右子樹組成的樹還想右子樹那樣處理
//對於左子樹回到了原問題,對於右子樹,左子樹的所有值都比右子樹的根小可以暫時把他看出右子樹的左子樹
//只需看看右子樹的右子樹是否符合要求即可
class Solution{ public: bool VerifySquenceOfBST(vector<int> sequence) { int size = sequence.size(); if(0==size)return false; int i = 0; while(--size) { while(sequence[i++]<sequence[size]); while(sequence[i++]>sequence[size]); if(i<size)return false; i=0; } return true; } };
/* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } };*/ class Solution { public: vector<vector<int> > FindPath(TreeNode* root,int expectNumber) { vector<vector<int> > ret; if(root==NULL) return ret; vector<int> line; findPath(root,expectNumber,0,line,ret); return ret; } void findPath(TreeNode* root,\ int expectNumber,\ int sum, vector<int> line, vector<vector<int> >& ret){ line.push_back(root->val); if(sum+root->val==expectNumber&&root->right==NULL\ &&root->right==NULL){ ret.push_back(line); return; } if(sum+root->val<expectNumber&&root->left) findPath(root->left,expectNumber,sum+root->val,line,ret); if(sum+root->val<expectNumber&&root->right) findPath(root->right,expectNumber,sum+root->val,line,ret); if(sum+root->val>expectNumber) return; } };
解題思路:分解步驟,簡化問題
1.將新鏈表每個節點依次連接到原鏈表節點的後面;
2.將複雜指針依次拷貝(此時新鏈表的複雜指針即指向原鏈表複雜指針的下一個節點);
3.將2個鏈表拆分;
/* struct RandomListNode { int label; struct RandomListNode *next, *random; RandomListNode(int x) : label(x), next(NULL), random(NULL) { } }; */ class Solution { public: RandomListNode* Clone(RandomListNode* pHead) { if(pHead==NULL) return NULL; RandomListNode* tmp=pHead; while(tmp){ RandomListNode* node=new RandomListNode(tmp->label); node->next=tmp->next; tmp->next=node; tmp=tmp->next->next; } tmp=pHead; RandomListNode* _next; while(tmp){ _next=tmp->next; if(tmp->random!=NULL) _next->random=tmp->random->next; tmp=tmp->next->next; } RandomListNode* newhead=pHead->next; RandomListNode* cur=newhead; tmp=pHead; while(cur->next){ tmp->next=tmp->next->next; cur->next=cur->next->next; tmp=tmp->next; cur=cur->next; } tmp->next=NULL; return newhead; } };
解題思路:
1.每棵二叉排序樹的最小節點 在最左子樹,藉助棧保存每個節點,一直壓左,知道左爲空
2.跳出壓左循環,棧不爲空,讓prev(上個節點)的右指向當前節點,出棧
3.當前節點的左指向prev,讓prev等於tmp(當前節點)
4.tmp的右不爲空,壓右
5.結束此次大循環
注意:藉助棧有可能形成死循環,因此要注意壓左的進入條件
pop的時間要用對,否則可能丟失節點
/* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } };*/ class Solution { public: TreeNode* Convert(TreeNode* pRootOfTree) { if(pRootOfTree==NULL) return NULL; stack<TreeNode*> stack; TreeNode* root=pRootOfTree; TreeNode* prev=NULL; TreeNode* head=NULL; stack.push(root); while(!stack.empty()){ TreeNode* tmp=stack.top(); while(tmp->left){ if(prev&&prev->right==NULL) break; stack.push(tmp->left); tmp=tmp->left; } if(prev&&!stack.empty()) prev->right=tmp; stack.pop(); if(head==NULL) head=tmp; tmp->left=prev; prev=tmp; if(tmp->right){ stack.push(tmp->right); } //else // if(prev&&!stack.empty()) // prev->right=stack.top(); } return head; } };
//附加條件 字符可能重複,但不能重複輸出,並且按字符順序輸出
思路:
1.字符全排列即從第一個字符開始 向後依次與每個字符交換位置 (遞歸過程)
2.因爲不能重複輸出,所以遇見相同字符不交換 跳過繼續
class Solution { public: vector<string> vec; vector<string> Permutation(string str) { if(str.size()<1) return vec; permutation(str,0,str.size()); return vec; } void permutation(string str,int begin,int size) { if(begin==size) vec.push_back(str); int i=begin; while(i<size){ if(str[i]==str[begin]&&i!=begin){ i++; continue; } swap(str[begin],str[i]); permutation(str,begin+1,size); // swap(str[begin],str[i]); i++; } } };