劍指offer 1-6

1. 二維數組中的查找node

在一個二維數組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。
 
分析:
從左下角(或右上角)開始判斷與要查找元素的大小,小於則向右走,大於則向上走。(相似與減而治之的思想,一次去掉一行或一列)。
時間複雜度O(m + n)
 
代碼:
 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 };
相關文章
相關標籤/搜索