1. 二維數組中的查找node
1 class Solution { 2 public: 3 bool Find(int target, vector<vector<int> > array) { 4 int s1 = array.size(), s2 = array[0].size(); 5 int i = s1 - 1, j = 0; 6 while (i >= 0 && j < s2) { 7 if (array[i][j] == target) { 8 return true; 9 } 10 else if (array[i][j] > target) { 11 i--; 12 } 13 else { 14 j++; 15 } 16 } 17 return false; 18 } 19 };
本題還可採用其餘分治策略,後續補充。數組
2. 替換空格app
請實現一個函數,將一個字符串中的空格替換成「%20」。例如,當字符串爲We Are Happy.則通過替換以後的字符串爲We%20Are%20Happy。函數
分析:spa
插入元素若是從前向後插入的話須要O(n^2)的時間複雜度,考慮先把空格個數算出,而後從後向前複製。設計
代碼:code
1 class Solution { 2 public: 3 void replaceSpace(char *str,int length) { 4 int blankSz = 0; 5 for (int i = 0; i < length; ++i) { 6 if (str[i] == ' ') { 7 blankSz ++; 8 } 9 } 10 int i = length - 1, j = length + 2 * blankSz - 1; 11 while (i >= 0) { 12 if (str[i] != ' ') { 13 str[j] = str[i]; 14 j--; 15 i--; 16 } else { 17 str[j] = '0'; 18 str[j - 1] = '2'; 19 str[j - 2] = '%'; 20 i--; 21 j -= 3; 22 } 23 } 24 } 25 };
3. 從尾到頭打印鏈表blog
輸入一個鏈表,從尾到頭打印鏈表每一個節點的值排序
分析:遞歸
方法1:利用一個棧,把元素以此壓棧,而後彈棧倒序輸出;
方法2:利用遞歸(本質利用了系統的棧)
代碼:
1 //方法1 2 class Solution { 3 public: 4 vector<int> printListFromTailToHead(ListNode* head) { 5 stack<int> st; 6 vector<int> result; 7 while (head != nullptr) { 8 st.push(head -> val); 9 head = head -> next; 10 } 11 while (!st.empty()) { 12 result.push_back(st.top()); 13 st.pop(); 14 } 15 return result; 16 } 17 }; 18 19 //方法2 20 class Solution { 21 private: 22 vector<int> result; 23 public: 24 vector<int> printListFromTailToHead(ListNode* head) { 25 if (head != nullptr) { 26 printListFromTailToHead(head -> next); 27 result.push_back(head -> val); 28 } 29 return result; 30 } 31 };
4. 重建二叉樹
輸入某二叉樹的前序遍歷和中序遍歷的結果,請重建出該二叉樹。假設輸入的前序遍歷和中序遍歷的結果中都不含重複的數字。例如輸入前序遍歷序列{1,2,4,7,3,5,6,8}和中序遍歷序列{4,7,2,1,5,3,8,6},則重建二叉樹並返回。
分析:
思路就是手動作二叉樹恢復的思路,在中序遍歷中找到根節點的位置,而後對左右子樹各自遞歸。注意代碼的寫法,helper函數的參數設計(要傳起始終止位置,不要拷貝vector)和傳遞(搞不清楚就舉例子)便可。
代碼:
1 class Solution { 2 private: 3 TreeNode* helper(const vector<int>& pre, int prevStart, int prevEnd, const vector<int>& vin, int vinStart, int vinEnd) { 4 if (prevStart == prevEnd) { 5 return nullptr; 6 } 7 if (prevEnd - prevStart == 1) { 8 TreeNode* result = new TreeNode(pre[prevStart]); 9 return result; 10 } 11 int rootVal = pre[prevStart]; 12 TreeNode* result = new TreeNode(rootVal); 13 int length = 0; 14 for (int i = vinStart; i < vinEnd; ++i) { 15 if (vin[i] != rootVal) { 16 length++; 17 } 18 else { 19 break; 20 } 21 } 22 result -> left = helper(pre, prevStart + 1, prevStart + length + 1, vin, vinStart, vinStart + length); 23 result -> right = helper(pre, prevStart + length + 1, prevEnd, vin, vinStart + length + 1, vinEnd); 24 return result; 25 } 26 public: 27 TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) { 28 TreeNode* result = helper(pre, 0, pre.size(), vin, 0, vin.size()); 29 return result; 30 } 31 };
5. 用兩個棧實現隊列
用兩個棧來實現一個隊列,完成隊列的Push和Pop操做。 隊列中的元素爲int類型。
分析:
思路1 stack1用來push, stack2用來pop(),每次pop()完把數據倒回到stack1中,保證知足隊列順序,但效率比較低;
思路2 stack1用來push, stack2用來pop(), 每次pop()前斷定stack2是否爲空,若是爲空則將stack1中元素均倒入stack2,而後再在stack2中pop(),不空直接pop()stack2
代碼:
1 //方法1 2 class Solution 3 { 4 public: 5 void push(int node) { 6 stack1.push(node); 7 } 8 9 int pop() { 10 while (!stack1.empty()) { 11 stack2.push(stack1.top()); 12 stack1.pop(); 13 } 14 int result = stack2.top(); 15 stack2.pop(); 16 while (!stack2.empty()) { 17 stack1.push(stack2.top()); 18 stack2.pop(); 19 } 20 return result; 21 22 } 23 24 private: 25 stack<int> stack1; 26 stack<int> stack2; 27 }; 28 29 //方法2 30 class Solution 31 { 32 public: 33 void push(int node) { 34 stack1.push(node); 35 } 36 37 int pop() { 38 if (stack2.empty()) { 39 while (!stack1.empty()) { 40 stack2.push(stack1.top()); 41 stack1.pop(); 42 } 43 } 44 int result = stack2.top(); 45 stack2.pop(); 46 return result; 47 48 } 49 50 private: 51 stack<int> stack1; 52 stack<int> stack2; 53 };
6. 旋轉數組的最小數字
把一個數組最開始的若干個元素搬到數組的末尾,咱們稱之爲數組的旋轉。輸入一個非遞減排序的數組的一個旋轉,輸出旋轉數組的最小元素。例如數組{3,4,5,1,2}爲{1,2,3,4,5}的一個旋轉,該數組的最小值爲1。NOTE:給出的全部元素都大於0,若數組大小爲0,請返回0。
分析:
思路1 二分搜索,用套路寫就行,注意的是,其實因爲更新start的條件只能在array[mid] > target時,start = mid,因此出循環後array[start]確定不是解,能夠不加那個判斷;
思路2 能夠用遞歸,注意分開兩個區間的時候,有可能一個區間是非旋轉的,因此遞歸終止條件是
if (rotateArray[0] <= rotateArray[n - 1]) { return rotateArray[0]; }
能夠同時處理兩種狀況。
代碼:
1 class Solution { 2 public: 3 int minNumberInRotateArray(vector<int> rotateArray) { 4 int start = 0, end = rotateArray.size() - 1; 5 while (start + 1 < end) { 6 int mid = start + (end - start) / 2; 7 if (rotateArray[mid] == rotateArray[0]) { 8 start = mid; 9 } 10 else if (rotateArray[mid] < rotateArray[0]) { 11 end = mid; 12 } 13 else { 14 start = mid; 15 } 16 } 17 return rotateArray[end]; 18 } 19 };