15道简单算法题

http://www.cnblogs.com/hlxs/archive/2014/06/06/3772333.html

(●—●) | 剑指Offer_编程题_牛客网

http://www.nowcoder.com/ta/coding-interviews?page=1

source code

https://github.com/haotang923/interview/tree/master/15%20simple%20algorithm%20problems

1:合并排序,将两个已经排序的数组合并成一个数组,其中一个数组能容下两个数组的所有元素;

 1 #include <iostream>
 2 using namespace std;
 3
 4 class Solution
 5 {
 6 public:
 7     void MergeArray(int a[],int alen,int b[],int blen)
 8     {
 9          int len = alen + blen - 1;
10          alen --;
11          blen --;
12
13          // 用归并排序的思想把两个数组合并
14          while (alen >= 0 && blen >= 0)
15          {
16                if (a[alen] > b[blen])
17                   a[len --] = a[alen --];
18                else
19                   a[len --] = b[blen --];
20          }
21
22          while (blen >= 0)
23                a[len --] = b[blen --];
24     }
25 };
26
27 int main ()
28 {
29     Solution testSolution;
30     int arrA[] = {1, 2, 4, 6, 8, 0, 0, 0, 0, 0};
31     int arrB[] = {1, 3, 5, 7, 9};
32
33     testSolution.MergeArray(arrA, 5, arrB, 5);
34
35     for (int i = 0; i < 10; i ++)
36         cout << arrA[i] << endl;
37
38     getchar();
39
40     return 0;
41 }

View Code

2:合并两个单链表;

  • C++11最好用nullptr初始化指针得到空指针,同时尽量避免使用NULL。

    • https://msdn.microsoft.com/zh-cn/library/4ex65770.aspx
  • 复习struct,链表也不熟悉了,用当前节点还是next节点的时候出了几次错。
  • struct_百度百科
    • http://baike.baidu.com/link?url=PxVQxXElF_rtYMqYhfNBzsjvTl9cG2PSKTqFZGV3IBAEHosImlkuaSMqCIxnShEqtDD4xA8gISTtP7rS7TENj_
  • struct (C++)
    • https://msdn.microsoft.com/zh-cn/library/64973255.aspx

  1 #include <iostream>
  2 using namespace std;
  3
  4 struct ListNode
  5 {
  6        int val;
  7        ListNode *next;
  8        ListNode(int x) : val(x), next(NULL) {}
  9 };
 10
 11 class Solution
 12 {
 13 public:
 14     ListNode* MergeList(ListNode* aListNode, ListNode* bListNode)
 15     {
 16          // NULL case
 17          if (aListNode == NULL)
 18             return bListNode;
 19          if (bListNode == NULL)
 20             return aListNode;
 21
 22          ListNode* resHead = NULL;
 23
 24          if (aListNode->val < bListNode->val) {
 25             resHead = aListNode;
 26             aListNode = aListNode->next;
 27          } else {
 28             resHead = bListNode;
 29             bListNode = bListNode->next;
 30          }
 31
 32          // Reserve the head point
 33          ListNode* tmpHead = resHead;
 34
 35 //         PrintListNode(tmpHead);
 36
 37          // Merge two LinkList
 38          // Remember to check if the current node is NULL
 39          // assign ListNode to next resHead->next
 40          // move resHead to the next ptr
 41          while (aListNode != NULL && bListNode != NULL)
 42          {
 43                if (aListNode->val < bListNode->val) {
 44                   resHead->next = aListNode;
 45                   aListNode = aListNode->next;
 46                } else {
 47                   resHead->next= bListNode;
 48                   bListNode = bListNode->next;
 49                }
 50                resHead = resHead->next;
 51          }
 52
 53 //         PrintListNode(tmpHead);
 54
 55          if (aListNode != NULL)
 56             resHead->next= aListNode;
 57
 58          if (bListNode != NULL)
 59             resHead->next= bListNode;
 60
 61 //         PrintListNode(tmpHead);
 62
 63          return tmpHead;
 64     }
 65
 66     void PrintListNode(ListNode* inListNode)
 67     {
 68          ListNode* tmpLN = inListNode;
 69
 70          while (tmpLN != NULL)
 71          {
 72                cout << tmpLN->val << endl;
 73                tmpLN = tmpLN->next;
 74          }
 75          cout << endl;
 76     }
 77 };
 78
 79 int main ()
 80 {
 81     Solution testSolution;
 82     ListNode* aHead = new ListNode(1);
 83     ListNode* cur = aHead;
 84
 85     for (int i = 2; i < 10; i += 2)
 86     {
 87         ListNode* tmpLN = new ListNode(i);
 88         cur->next = tmpLN;
 89         cur = tmpLN;
 90     }
 91
 92 //    testSolution.PrintListNode(aHead);
 93
 94     ListNode* bHead = new ListNode(1);
 95     cur = bHead;
 96
 97     for (int i = 3; i < 10; i += 2)
 98     {
 99         ListNode* tmpLN = new ListNode(i);
100         cur->next = tmpLN;
101         cur = tmpLN;
102     }
103
104 //    testSolution.PrintListNode(bHead);
105
106     ListNode* head = testSolution.MergeList(aHead, bHead);
107
108 //    testSolution.PrintListNode(head);
109
110     while (head != NULL)
111     {
112           cout << head->val << endl;
113           head = head->next;
114     }
115
116     getchar();
117
118     return 0;
119 }

View Code

3:倒序打印一个单链表;

  • 递归
  • 链表的题目还得多练,又弄错了打印head还是cur节点。。。

 1 #include <iostream>
 2 using namespace std;
 3
 4 struct ListNode
 5 {
 6        int val;
 7        ListNode *next;
 8        ListNode(int x) : val(x), next(NULL) {}
 9 };
10
11 class Solution
12 {
13 public:
14     void PrintListNodeReversely(ListNode* inListNode)
15     {
16          if (inListNode != NULL)
17          {
18             PrintListNodeReversely(inListNode->next);
19             cout << inListNode->val << endl;
20          }
21     }
22 };
23
24 int main ()
25 {
26     Solution testSolution;
27     ListNode* head = new ListNode(0);
28     ListNode* cur = head;
29
30     for (int i = 1; i < 10; i ++)
31     {
32         ListNode* tmpLN = new ListNode(i);
33         cur->next = tmpLN;
34         cur = cur->next; // cur->next == tmpLN
35     }
36
37     // Print head node
38     testSolution.PrintListNodeReversely(head);
39
40     getchar();
41
42     return 0;
43 }

View Code

4:给定一个单链表的头指针和一个指定节点的指针,在O(1)时间删除该节点;

  • http://www.cnblogs.com/pegasus923/archive/2010/10/04/1841891.html
  • 重温链表插入删除操作,注意原文代码删除头结点处有问题,函数对头指针只是值传递,如果要删除需要传入头指针的指针。

  1 #include <iostream>
  2 using namespace std;
  3
  4 struct ListNode
  5 {
  6        int val;
  7        ListNode *next;
  8        ListNode(int x) : val(x), next(NULL) {}
  9 };
 10
 11 class Solution
 12 {
 13 public:
 14     void PrintListNode(ListNode* inListNode)
 15     {
 16          if (inListNode != NULL) {
 17             cout << inListNode->val << endl;
 18             PrintListNode(inListNode->next);
 19          } else
 20             cout << endl;
 21     }
 22
 23     void Test(ListNode* inListNode)
 24     {
 25          delete inListNode;
 26          inListNode = NULL;
 27          cout << inListNode << endl;
 28
 29          PrintListNode(inListNode);
 30     }
 31
 32     void DeleteNode(ListNode* pInHead, ListNode* pToBeDeleted)
 33     {
 34          cout << "Entry void DeleteNode(ListNode* pInHead, ListNode* pToBeDeleted)\n" << endl;
 35
 36          // Check NULL always
 37          if (pInHead == NULL || pToBeDeleted == NULL)
 38             return;
 39
 40 //         PrintListNode(pInHead);
 41
 42          // Delete non-tail node including head node
 43          if (pToBeDeleted->next != NULL) {
 44             ListNode* pNext = pToBeDeleted->next;
 45             pToBeDeleted->val = pNext->val;
 46             pToBeDeleted->next = pNext->next;
 47
 48             delete pNext;
 49             pNext = NULL;
 50          } else { // Delete tail
 51             ListNode* pPre = pInHead;
 52
 53             while (pPre->next != pToBeDeleted && pPre != NULL)
 54                   pPre = pPre->next;
 55
 56             if (pPre == NULL)
 57                return;
 58
 59             pPre->next = NULL;
 60             delete pToBeDeleted;
 61             pToBeDeleted = NULL;
 62          }
 63     }
 64 };
 65
 66 int main ()
 67 {
 68     Solution testSolution;
 69     int count = 5;
 70
 71     for (int k = 0; k <= count; k ++)
 72     {
 73         ListNode* pHead = NULL;
 74         ListNode* pCur = NULL;
 75         ListNode* pDel = NULL;
 76
 77         for (int i = 0; i < count; i ++)
 78         {
 79             ListNode* pTemp = new ListNode(i);
 80
 81             if (i == 0)
 82                 pHead = pCur = pTemp;
 83             else {
 84                 pCur->next = pTemp;
 85                 pCur = pCur->next; // pCur->next == pTemp
 86             }
 87
 88             if (i == k)
 89                pDel = pTemp;
 90         }
 91
 92         cout << "pHead = " << pHead << endl;
 93         if (pHead != NULL)
 94            cout << "pHead->val = " << pHead->val << endl;
 95         cout << "pDel = " << pDel << endl;
 96         if (pDel != NULL)
 97            cout << "pDel->val = " << pDel->val << endl;
 98         cout << ((pHead == pDel) ? "pHead == pDel" : "pHead != pDel") << endl;
 99         cout << endl;
100
101        // Print Linkedlist
102         testSolution.PrintListNode(pHead);
103
104         testSolution.DeleteNode(pHead, pDel);
105 //        testSolution.Test(pHead);
106
107 /*
108         delete pDel;
109         pDel = NULL;
110         pHead = NULL;
111 */
112         cout << "pHead = " << pHead << endl;
113         if (pHead != NULL)
114            cout << "pHead->val = " << pHead->val << endl;
115         cout << "pDel = " << pDel << endl;
116         if (pDel != NULL)
117            cout << "pDel->val = " << pDel->val << endl;
118         cout << endl;
119
120         // Print Linkedlist
121         testSolution.PrintListNode(pHead);
122     }
123
124     getchar();
125
126     return 0;
127 }

View Code

5:找到链表倒数第K个节点; K=0时,返回链表尾元素。

  • 两个指针同时往后走,之间相隔K个元素。一个到达尾部时,另一个正好为倒数第K个。
  • 注意边界情况,头指针为NULL,K为0,K大于链表长度。

  1 #include <iostream>
  2 using namespace std;
  3
  4 struct ListNode
  5 {
  6        int val;
  7        ListNode *next;
  8        ListNode(int x) : val(x), next(NULL) {}
  9 };
 10
 11 class Solution
 12 {
 13 public:
 14     void PrintListNode(ListNode* inListNode)
 15     {
 16          if (inListNode != NULL) {
 17             cout << inListNode->val << endl;
 18             PrintListNode(inListNode->next);
 19          } else
 20             cout << endl;
 21     }
 22
 23     ListNode *findMToLastElement(ListNode* pInHead, int m)
 24     {
 25          cout << "Entry ListNode *findMToLastElement(ListNode* pInHead, int m)\n" << endl;
 26
 27          ListNode *pCur = NULL, *pMPre = NULL;
 28
 29          // Corner case
 30          if (pInHead == NULL) return NULL;
 31
 32          pCur = pMPre = pInHead;
 33
 34          // Move pCur forward m elements
 35          for (int i = 0; i < m; i ++)
 36          {
 37              if (pCur->next != NULL)
 38                 pCur = pCur->next;
 39              else
 40                 return NULL;
 41          }
 42
 43          // Move forward together until pCur reach the tail
 44          while (pCur->next != NULL)
 45          {
 46                pCur = pCur->next;
 47                pMPre = pMPre->next;
 48          }
 49
 50          // Now pMPre points to the M to last element
 51          return pMPre;
 52     }
 53 };
 54
 55 int main ()
 56 {
 57     Solution testSolution;
 58     int count = 10;
 59
 60     ListNode *pHead = NULL;
 61     ListNode *pCur = NULL;
 62
 63     for (int i = 0; i < count; i ++)
 64     {
 65         ListNode *pTemp = new ListNode(i);
 66
 67         if (i == 0)
 68             pHead = pCur = pTemp;
 69         else {
 70             pCur->next = pTemp;
 71             pCur = pCur->next; // pCur->next == pTemp
 72         }
 73     }
 74
 75     // Print Head
 76     cout << "pHead = " << pHead << endl;
 77     if (pHead != NULL)
 78        cout << "pHead->val = " << pHead->val << endl;
 79     cout << endl;
 80
 81     // Print Linkedlist
 82     cout << "PrintListNode(pHead)" << endl;
 83     testSolution.PrintListNode(pHead);
 84
 85     cout << "Test findMToLastElement(pHead, 0)\n" << endl;
 86     ListNode *pMToLastElement = testSolution.findMToLastElement(pHead, 0);
 87
 88     // Print Head
 89     cout << "pHead = " << pHead << endl;
 90     if (pHead != NULL)
 91        cout << "pHead->val = " << pHead->val << endl;
 92     cout << endl;
 93
 94     // Print M to last element
 95     cout << "pMToLastElement = " << pMToLastElement << endl;
 96     if (pMToLastElement != NULL)
 97        cout << "pMToLastElement->val = " << pMToLastElement->val << endl;
 98     cout << endl;
 99
100     getchar();
101
102     return 0;
103 }

View Code

6:反转单链表;

  • 注意保留反转时,先保留next指针地址,反转之后再赋值给current指针往后走,否则丢了next指针。

  1 #include <iostream>
  2 using namespace std;
  3
  4 struct ListNode
  5 {
  6        int val;
  7        ListNode *next;
  8        ListNode(int x = 0) : val(x), next(NULL) {}
  9 };
 10
 11 class Solution
 12 {
 13 public:
 14     void PrintList(ListNode *inListNode)
 15     {
 16          if (inListNode != NULL) {
 17             cout << inListNode->val << endl;
 18             PrintList(inListNode->next);
 19          } else
 20             cout << "NULL\n" << endl;
 21     }
 22
 23     // Assign in ptr of the head ptr
 24     void DeleteList(ListNode **pInHead)
 25     {
 26          cout << "Entry void DeleteList(ListNode **pInHead)\n" << endl;
 27
 28          ListNode *pDel = *pInHead;
 29
 30          while (pDel != NULL)
 31          {
 32                // Reserve the address of the next node
 33                ListNode *pNext = pDel->next;
 34                // Delete the current node
 35                delete pDel;
 36                pDel = NULL;
 37                // Move to the next node
 38                pDel = pNext;
 39          }
 40
 41          // Set head to NULL
 42          *pInHead = NULL;
 43     }
 44
 45     ListNode* ReverseList(ListNode* pHead)
 46     {
 47          cout << "Entry ListNode* ReverseList(ListNode* pHead)\n" << endl;
 48
 49          // Corner case
 50          if (pHead == NULL)       return NULL;
 51
 52          ListNode *pPre = NULL, *pRHead = NULL, *pCur = pHead;
 53
 54          while (pCur != NULL)
 55          {
 56                // Reserve the next node
 57                ListNode *pNext = pCur->next;
 58                // Reserve the address of the last node of original list
 59                if (pNext == NULL) pRHead = pCur;
 60                // Insert current node
 61                pCur->next = pPre;
 62                // Move the previous ptr
 63                pPre = pCur;
 64                // Assign the next node back
 65                pCur = pNext;
 66          }
 67
 68          return pRHead;
 69     }
 70 };
 71
 72 int main ()
 73 {
 74     Solution testSolution;
 75     int count = 10;
 76
 77     ListNode *pMHead = NULL;
 78     ListNode *pMCur = NULL;
 79
 80     for (int i = 0; i < count; i ++)
 81     {
 82         ListNode *pTemp = new ListNode(i);
 83
 84         if (i == 0)
 85             pMHead = pMCur = pTemp;
 86         else {
 87             pMCur->next = pTemp;
 88             pMCur = pMCur->next; // pCur->next == pTemp
 89         }
 90     }
 91
 92     // Print Head
 93     cout << "pMHead = " << pMHead << endl;
 94     if (pMHead != NULL)
 95        cout << "pMHead->val = " << pMHead->val << endl;
 96     cout << endl;
 97
 98     // Print Linkedlist
 99     cout << "PrintList(pMHead)" << endl;
100     testSolution.PrintList(pMHead);
101
102     cout << "Test ReverseList(pMHead)\n" << endl;
103     ListNode *pMRHead = testSolution.ReverseList(pMHead);
104
105     // Print Reversed Head
106     cout << "pMRHead = " << pMRHead << endl;
107     if (pMRHead != NULL)
108        cout << "pMRHead->val = " << pMRHead->val << endl;
109     cout << endl;
110
111     // Print Linkedlist
112     cout << "PrintList(pMRHead)" << endl;
113     testSolution.PrintList(pMRHead);
114
115     // Print Head
116     cout << "pMHead = " << pMHead << endl;
117     if (pMHead != NULL)
118        cout << "pMHead->val = " << pMHead->val << endl;
119     cout << endl;
120
121     // Print Linkedlist
122     cout << "PrintList(pMHead)" << endl;
123     testSolution.PrintList(pMHead);
124
125     cout << "DeleteList(&pMRHead)" << endl;
126     testSolution.DeleteList(&pMRHead);
127
128     // Print Reversed Head
129     cout << "pMRHead = " << pMRHead << endl;
130     if (pMRHead != NULL)
131        cout << "pMRHead->val = " << pMRHead->val << endl;
132     cout << endl;
133
134     // Print Linkedlist
135     cout << "PrintList(pMRHead)" << endl;
136     testSolution.PrintList(pMRHead);
137
138     // Print Head
139     cout << "pMHead = " << pMHead << endl; // It is not NULL, the space is free'ed?
140     if (pMHead != NULL)
141        cout << "pMHead->val = " << pMHead->val << endl;
142     cout << endl;
143
144     // Print Linkedlist
145 //    cout << "PrintList(pMHead)" << endl;
146 //    testSolution.PrintList(pMHead);
147
148     getchar();
149
150     return 0;
151 }

View Code

7:通过两个栈实现一个队列;

  • stack 类

    • https://msdn.microsoft.com/zh-cn/library/56fa1zk5.aspx
  • stack - C++ Reference
    •   http://www.cplusplus.com/reference/stack/stack/
  • Stack_百度百科
    • http://baike.baidu.com/link?url=umZEKUINQtIeQve3VZ9u7eJSI2IvARxNaxZus-XwejEcV2QSUjgD-qNQS-efMtjl_96xGF_LXYyUuGO0-ewAzq#5

 1 #include <iostream>
 2 #include <stack>
 3 using namespace std;
 4
 5 class Solution
 6 {
 7 public:
 8        void push(int node)
 9        {
10             stack1.push(node);
11        }
12
13        int pop()
14        {
15             int result = 0;
16
17             if (stack2.empty())
18             {
19                 while (!stack1.empty())
20                 {
21                       stack2.push(stack1.top());
22                       stack1.pop();
23                 }
24             }
25
26             result = stack2.top();
27             stack2.pop();
28
29             return result;
30        }
31
32 private:
33     stack<int> stack1;
34     stack<int> stack2;
35 };
36
37 int main ()
38 {
39     Solution testSolution;
40     int count = 10;
41
42     // Case 1
43     cout << "CASE 1\n" << endl;
44
45     for (int i = 0; i < count; i ++)
46     {
47         testSolution.push(i);
48     }
49
50     for (int i = 0; i < count; i ++)
51     {
52         cout << testSolution.pop() << endl;
53     }
54
55     // Case 2
56     cout << "\nCASE 2\n" << endl;
57
58     for (int i = 0; i < count; i ++)
59     {
60         testSolution.push(i);
61         cout << testSolution.pop() << endl;
62     }
63
64     // Case 3
65     cout << "\nCASE 3\n" << endl;
66
67     for (int i = 0; i < count / 2; i ++)
68     {
69         testSolution.push(i);
70     }
71
72     cout << testSolution.pop() << "\n" << endl;
73
74     for (int i = count / 2; i < count; i ++)
75     {
76         testSolution.push(i);
77     }
78
79     for (int i = 0; i < count - 1; i ++)
80     {
81         cout << testSolution.pop() << endl;
82     }
83
84     getchar();
85
86     return 0;
87 }

View Code

8:二分查找;

  • 用vector实现递归和非递归二分查找。刚开始没弄清元素个数,初始化1个元素,再push_back n-1个元素,这时vector里应该是n个元素。
  • iterator作为入参传递有问题,先用int代替了,以后再研究
  • 用distance来计算找到的当前元素是第几个元素
  • vector的二分查找算法 - 轻典 - 博客园
  •   http://www.cnblogs.com/tianyajuanke/archive/2012/05/23/2515117.html
  • distance - C++ Reference
  •   http://www.cplusplus.com/reference/iterator/distance/
  • distance
  •   https://msdn.microsoft.com/zh-cn/library/k1kfxk7e.aspx

 1 #include <iostream>
 2 #include <vector>
 3 #include <iterator>
 4 using namespace std;
 5
 6 class Solution
 7 {
 8 public:
 9     int binarySearch(vector<int> array, int target)
10     {
11         vector<int>::iterator     vecBIT = array.begin();
12         vector<int>::iterator     vecEIT = array.end();
13         vector<int>::iterator     vecIT = vecBIT + (vecEIT - vecBIT) / 2;
14
15         while (vecBIT <= vecEIT)
16         {
17               if (*vecIT == target)
18                   return distance(array.begin(), vecIT); // Return distance between iterators
19               else if (*vecIT < target)
20               {
21                   vecBIT = vecIT + 1;
22                   vecIT = vecBIT + (vecEIT - vecBIT) / 2;
23               }
24               else
25               {
26                   vecEIT = vecIT - 1;
27                   vecIT = vecBIT + (vecEIT - vecBIT) / 2;
28               }
29         }
30
31         if (vecBIT > vecEIT) return -1;
32     }
33
34     int binarySearchRecursion(vector<int> array, int vecBIT, int vecEIT, int target)
35     {
36 //        cout << "Entry int binarySearchRecursion(vector<int> array, vector<int>::iterator vecBIT, vector<int>::iterator vecEIT, int target)\n" << endl;
37
38         if (vecBIT <= vecEIT)
39         {
40             int    vecIT = vecBIT + (vecEIT - vecBIT) / 2;
41
42             if (array[vecIT] == target)
43               return vecIT;
44             else if (array[vecIT] < target)
45               return binarySearchRecursion(array, vecIT + 1, vecEIT, target);
46             else
47               return binarySearchRecursion(array, vecBIT, vecIT - 1, target);
48         }
49         else
50             return -1;
51     }
52 };
53
54 int main ()
55 {
56     Solution testSolution;
57     int n = 3;
58     vector<int> searchArray(1); // initialize vector of n elements with 0
59
60     // push_back another n - 1 elements
61     for (int i = 1; i < n; i ++)
62         searchArray.push_back(i);
63
64     // n element in vector now
65     for (vector<int>::const_iterator vecIT = searchArray.begin(); vecIT < searchArray.end(); vecIT ++)
66         cout << *vecIT << endl;
67     cout << endl;
68
69     cout << distance(searchArray.begin(), searchArray.end()) << "\n" << endl;
70
71     for (int i = 0; i <= n; i ++)
72     {
73         cout << testSolution.binarySearch(searchArray, i) << endl;
74         cout << testSolution.binarySearchRecursion(searchArray, 0, n, i) << endl;
75     }
76
77     getchar();
78
79     return 0;
80 }

View Code

9:快速排序;

  • 注意对vector入参要用引用,不能用形参,否则对vector元素排序不起作用
  • vector有序情况下,快排时间复杂度最高退化为O(N^2)
  • 输出vector也可以使用范围for语句
    • for (auto vecCIT : vecArray) cout << vecCIT << endl;

 1 #include <iostream>
 2 #include <vector>
 3 using namespace std;
 4
 5 class Solution
 6 {
 7 public:
 8     // Pass in reference of vector parameter
 9     void quickSort(vector<int> &a, int inLeft, int inRight)
10     {
11         cout << "Entry void qSort(vector<int> array, int left, int right)\n" << endl;
12
13         if (inLeft >= inRight)
14            return;
15
16         int i = inLeft, j = inRight, temp = a[inLeft];
17
18         while (i < j)
19         {
20               // Scan from right to left
21               while ((i < j) && (a[j] >= temp))
22                     j --;
23               if (i < j)
24                  a[i ++] = a[j];
25
26               // Scan from left to right
27               while ((i < j) && (a[i] <= temp))
28                     i ++;
29               if (i < j)
30                  a[j --] = a[i];
31         }
32         // Base value temp is on the right position
33         a[i] = temp;
34
35         // Divide and conquer
36         quickSort(a, inLeft, i - 1);
37         quickSort(a, i + 1, inRight);
38     }
39 };
40
41 int main ()
42 {
43     Solution testSolution;
44     int array[] = {0, 1, 5, 9, 0, 2, 6, 7, 8, 3, 4};
45 //    int array[] = {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
46 //    int array[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0};
47 //    int array[] = {9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9};
48     vector<int> vecArray(array, array + 11);
49
50     for (vector<int>::const_iterator vecCIT = vecArray.begin(); vecCIT != vecArray.end(); vecCIT ++)
51         cout << *vecCIT << endl;
52     cout << endl;
53
54     testSolution.quickSort(vecArray, 0, vecArray.size() - 1);
55
56     for (vector<int>::const_iterator vecCIT = vecArray.begin(); vecCIT != vecArray.end(); vecCIT ++)
57         cout << *vecCIT << endl;
58     cout << endl;
59
60     getchar();
61
62     return 0;
63 }

View Code

10:获得一个int型的数中二进制中1的个数; 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

  • 位运算
  • 如果不是负数的话,可以一直右移获取1的个数,f(n) = f(n / 2) + n % 2。跟LeetCode 338 Counting Bits一样。
    •   http://www.cnblogs.com/pegasus923/p/5499737.html
  • 负数用补码表示。所以只能用n = n & (n - 1),用n跟n-1做&运算,把二进制中的1从后往前去掉,直到没有。注意2的幂的特征(n & (n - 1)) == 0,e.g. 0x1000 & 0x0111。
  • 补码_百度百科
    •   http://baike.baidu.com/link?url=ITDahaDRGLVt2jyxtz0t3a7DbXYFBk1kVZMxzX7SsmxRnTpPBYKHCBYM2zFs1t3s6FrDlgFoYqtTZnnbWClt6a

 1 #include <iostream>
 2 using namespace std;
 3
 4 class Solution
 5 {
 6 public:
 7     int  NumberOf1(int n)
 8     {
 9         cout << "Entry int  NumberOf1(int n)\n" << endl;
10
11         if (n == 0) return 0;
12
13         int count = 0;
14
15         while (n != 0)
16         {
17               n = n & (n - 1);
18               count ++;
19         }
20
21         return count;
22     }
23 };
24
25 int main ()
26 {
27     Solution testSolution;
28     int n = 10;
29
30     for (int i = 0; i < n; i ++)
31         cout << testSolution.NumberOf1(i) << endl;
32
33     getchar();
34
35     return 0;
36 }

View Code

11:输入一个数组,实现一个函数,让所有奇数都在偶数前面; 并保证奇数和奇数,偶数和偶数之间的相对位置不变。

  • 跟排序思想差不多。原文的思想类似快排,两个指针一个从头往后找偶数,另一个从尾往前找奇数,找到就交换,直到两个指针相遇。但这个是不稳定的,所以奇偶数之间的相对位置会变。可以用归并,冒泡排序思想,这些都是稳定的。
  • 另一种解法就是借助辅助vector存储偶数,扫描一遍把偶数挑出来并从原vector删除,之后再push_back回去。
  • 注意vector.end()并不是最后一个元素,而是vector结束符。要找最后一个元素的下标是vector.end()-1。

 1 #include <iostream>
 2 #include <vector>
 3 using namespace std;
 4
 5 class Solution
 6 {
 7 public:
 8     void reOrderArray(vector<int> &array)
 9     {
10         cout << "Entry void reOrderArray(vector<int> &array)\n" << endl;
11
12         vector<int> vecEven; // Store even
13
14         for (vector<int>::iterator vecIT = array.begin(); vecIT != array.end(); )
15             if ((*vecIT % 2) == 0)
16             {
17                          vecEven.push_back(*vecIT);
18                          vecIT = array.erase(vecIT);
19             }
20             else
21                 vecIT ++;
22
23         for (vector<int>::const_iterator vecCIT = vecEven.begin(); vecCIT != vecEven.end(); vecCIT ++)
24             array.push_back(*vecCIT);
25     }
26 };
27
28 int main ()
29 {
30     Solution testSolution;
31     int array[] = {0, 1, 5, 9, 2, 6, 7, 8, 3, 4};
32     vector<int> vecArray(array, array + 10);
33
34     for (vector<int>::const_iterator vecCIT = vecArray.begin(); vecCIT != vecArray.end(); vecCIT ++)
35         cout << *vecCIT << endl;
36     cout << endl;
37
38     testSolution.reOrderArray(vecArray);
39
40     for (vector<int>::const_iterator vecCIT = vecArray.begin(); vecCIT != vecArray.end(); vecCIT ++)
41         cout << *vecCIT << endl;
42     cout << endl;
43
44     getchar();
45
46     return 0;
47 }

View Code

12:判断一个字符串是否是另一个字符串的子串;

  • 简单的暴力匹配。关键是熟悉string函数,不出BUG。
  • kmp算法_百度百科
    •   http://baike.baidu.com/view/659777.htm
  • 字符串匹配的KMP算法_知识库_博客园
    •   http://kb.cnblogs.com/page/176818/
  • 字符串匹配的Boyer-Moore算法_知识库_博客园
    •   http://kb.cnblogs.com/page/176945/
  • KMP算法详解
    •   http://www.matrix67.com/blog/archives/115

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4
 5 class Solution {
 6 public:
 7     int substr(const string source, const string sub)
 8     {
 9         // Corner case
10         if (sub.empty()) return 0;
11         if (source.empty()) return -1;
12
13         int n = source.length() - sub.length() + 1;
14
15         // better use < rather than <=
16         for (int i = 0; i < n; i ++)
17         {
18               bool flag = true;
19
20               for (int j = 0; j < sub.length(); j ++)
21               {
22                   if (source.at(i + j) != sub.at(j))
23                   {
24                     flag = false;
25                     break;
26                   }
27               }
28
29               if (flag) return i;
30         }
31
32         return -1;
33     }
34 };
35
36 int main ()
37 {
38     Solution testSolution;
39     string s1 = "mississippi";
40     string s2 = "issi";
41
42     cout << testSolution.substr(s1, s2) << endl;
43
44     getchar();
45
46     return 0;
47 }

View Code

13:把一个int型数组中的数字拼成一个串,这个串代表的数字最小;

  • 把数组转成字符串然后进行升序排序,定义如果AB < BA,那么A < B。排序完成,再把数组组合就成了最小串了。
  • 学习了sort的比较函数的写法。注意类中自定义的compare需要定义成static,否则sort函数编译出错。
  • 学习了int跟string转换的几种方法,to_string方便只是是C++11的。
  • sort - C++ Reference
    •   http://www.cplusplus.com/reference/algorithm/sort/?kw=sort
  • sort
    •   https://msdn.microsoft.com/zh-cn/library/ecdecxh1(v=vs.110).aspx
  • STL 中sort、qsort 的用法 - rattles的专栏 - 博客频道 - CSDN.NET
    •   http://blog.csdn.net/rattles/article/details/5510919
  • C++中Static作用和使用方法
    •   http://blog.csdn.net/artechtor/article/details/2312766
  • sprintf - C++ Reference
    •   http://www.cplusplus.com/reference/cstdio/sprintf/
  • sprintf、_sprintf_l、swprintf、_swprintf_l、__swprintf_l
    •   https://msdn.microsoft.com/zh-cn/library/ybk95axf.aspx
  • to_string - C++ Reference
    •   http://www.cplusplus.com/reference/string/to_string/
  • C++ int与string的转化 - Andy Niu - 博客园
    •   http://www.cnblogs.com/nzbbody/p/3504199.html

 1 #include <iostream>
 2 #include <vector>
 3 #include <cstdio> // sprintf
 4 #include <algorithm>  // sort
 5 using namespace std;
 6
 7 class Solution
 8 {
 9 public:
10     // Need to define static
11     static bool compare(const string &sA, const string &sB)
12     {
13            string sAB = sA + sB;
14            string sBA = sB + sA;
15
16          return sAB < sBA;
17     }
18
19     string PrintMinNumber(vector<int> numbers)
20     {
21         cout << "Entry string PrintMinNumber(vector<int> numbers)\n" << endl;
22
23         string result = "";
24
25         // Corner case
26         if (numbers.size() == 0) return result;
27
28         vector<string> sNumbers;
29         char *sTemp = new char[10]; // Remember to initialize ptr
30
31         for (vector<int>::const_iterator vecCIT = numbers.begin(); vecCIT != numbers.end(); vecCIT ++)
32         {
33 //         string sTemp = to_string(*vecCIT); // C++11
34             sprintf(sTemp, "%d", *vecCIT);
35             sNumbers.push_back(sTemp);
36         }
37
38         // Use self-defined compare function
39         sort(sNumbers.begin(), sNumbers.end(), compare);
40
41         for (vector<string>::const_iterator vecCIT = sNumbers.begin(); vecCIT != sNumbers.end(); vecCIT ++)
42             result += *vecCIT;
43
44         return result;
45     }
46 };
47
48 int main ()
49 {
50     Solution testSolution;
51     int array[] = {3, 32, 321};
52     vector<int> vecArray(array, array + 3);
53 //    vector<int> vecArray;
54
55     for (vector<int>::const_iterator vecCIT = vecArray.begin(); vecCIT != vecArray.end(); vecCIT ++)
56         cout << *vecCIT << endl;
57     cout << endl;
58
59     cout << testSolution.PrintMinNumber(vecArray) << endl;
60
61     getchar();
62
63     return 0;
64 }

View Code

14:输入一颗二叉树,输出它的镜像(每个节点的左右子节点交换位置);

  • 交换左右子节点(注意是节点,不只是值),然后递归处理左右子树。
  • 复习了建树过程。
  • swap - C++ Reference
    •   http://www.cplusplus.com/reference/utility/swap/?kw=swap

 1 #include <iostream>
 2 #include <vector>
 3 using namespace std;
 4
 5 struct TreeNode {
 6     int val;
 7     struct TreeNode *left;
 8     struct TreeNode *right;
 9     TreeNode(int x) :
10             val(x), left(NULL), right(NULL) {
11     }
12 };
13
14 class Solution
15 {
16 public:
17     TreeNode* CreateTree(const vector<int> &vec, const int &pos)
18     {
19 //              cout << "Entry TreeNode* CreateTree(const vector<int> &vec, const int &pos)\n" << endl;
20
21 //              cout << "pos = " << pos << endl;
22 //              cout << "vec.size() = " << vec.size() << endl;
23
24               // Pay attention to >=, or else infinite loop
25               if (pos >= vec.size()) return NULL;
26
27 //              cout << "vec[pos] = " << vec[pos] << endl;
28
29               TreeNode *pCur = new TreeNode(vec[pos]);
30 //              cout << "pCur->val = " << pCur->val<< endl;
31               pCur->left = CreateTree(vec, 2 * pos);
32               pCur->right = CreateTree(vec, 2 * pos + 1);
33
34               return pCur;
35     }
36
37     void PrintTree(TreeNode *pTreeNode)
38     {
39          if (pTreeNode != NULL) {
40             cout << pTreeNode->val << endl;
41             PrintTree(pTreeNode->left);
42             PrintTree(pTreeNode->right);
43          }
44     }
45
46     void Mirror(TreeNode *pRoot)
47     {
48 //         cout << "Entry void Mirror(TreeNode *pRoot) " << endl;
49
50          // Corner case
51          if ((pRoot == NULL) || ((pRoot->left == NULL) && (pRoot->right == NULL))) return;
52
53          // swap two ptr rathet than value
54          swap(pRoot->left, pRoot->right);
55
56          Mirror(pRoot->left);
57          Mirror(pRoot->right);
58     }
59 };
60
61 int main ()
62 {
63     Solution testSolution;
64     int count = 8;
65     int array[] = {0, 8, 6, 10, 5, 7, 9, 11};
66     vector<int> vecArray(array, array + count);
67
68     TreeNode *pMRoot = testSolution.CreateTree(vecArray, 1);
69 /*
70     cout << root << endl;
71     cout << root->val << endl;
72 */
73     testSolution.PrintTree(pMRoot);
74     cout << endl;
75
76     testSolution.Mirror(pMRoot);
77
78     testSolution.PrintTree(pMRoot);
79     cout << endl;
80
81     getchar();
82
83     return 0;
84 }

View Code

15:输入两个链表,找到它们第一个公共节点;

  • 若有公共节点,则从公共节点之后的所有节点都是公共的。I.e. 短链表是长链表的子串。基于这个思想,长链表里的公共节点只可能出现在倒数K个节点里(K为短链表长度)。长链表先走N-K步,长度相同时再开始往后挨个找。

  1 #include <iostream>
  2 using namespace std;
  3
  4 struct ListNode
  5 {
  6        int val;
  7        ListNode *next;
  8        ListNode(int x = 0) : val(x), next(NULL) {}
  9 };
 10
 11 class Solution
 12 {
 13 public:
 14     void PrintList(ListNode *pListNode)
 15     {
 16          if (pListNode != NULL) {
 17             cout << pListNode->val << endl;
 18             PrintList(pListNode->next);
 19          } else
 20             cout << "NULL\n" << endl;
 21     }
 22
 23     int getLengthOfList(const ListNode *pListNode)
 24     {
 25         int length = 0;
 26
 27         while (pListNode != NULL)
 28         {
 29               pListNode = pListNode->next;
 30               length ++;
 31         }
 32
 33         return length;
 34     }
 35
 36     ListNode* FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2)
 37     {
 38 //              cout << "Entry ListNode* FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2)" << endl;
 39
 40               int len1 = getLengthOfList(pHead1);
 41               int len2 = getLengthOfList(pHead2);
 42
 43               if (len1 > len2)
 44               {
 45                     int gap = len1 - len2;
 46                     for (int i = 0; i < gap; i ++)
 47                         pHead1 = pHead1->next;
 48               }
 49               else
 50               {
 51                     int gap = len2 - len1;
 52                     for (int i = 0; i < gap; i ++)
 53                        pHead2 = pHead2->next;
 54               }
 55
 56               while ((pHead1 != NULL) && (pHead2 != NULL) && (pHead1 != pHead2))
 57               {
 58                     pHead1 = pHead1->next;
 59                     pHead2 = pHead2->next;
 60               }
 61
 62               return pHead1;
 63     }
 64 };
 65
 66 int main ()
 67 {
 68     Solution testSolution;
 69     int count = 10, k = 0;
 70
 71     ListNode *pMHead = NULL;
 72     ListNode *pMCur = NULL;
 73     ListNode *pKNode = NULL;
 74
 75     for (int i = 0; i < count; i ++)
 76     {
 77         ListNode *pTemp = new ListNode(i);
 78
 79         if (i == 0)
 80             pMHead = pMCur = pTemp;
 81         else {
 82             pMCur->next = pTemp;
 83             pMCur = pMCur->next; // pMCur->next == pTemp
 84         }
 85
 86         if (i == k)
 87            pKNode = pMCur;
 88     }
 89
 90     // Print Head
 91     cout << "pMHead = " << pMHead << endl;
 92     if (pMHead != NULL)
 93        cout << "pMHead->val = " << pMHead->val << endl;
 94     cout << endl;
 95
 96     // Print Kth Node
 97     cout << "pKNode = " << pKNode << endl;
 98     if (pKNode != NULL)
 99        cout << "pKNode->val = " << pKNode->val << endl;
100     cout << endl;
101
102     // Print Linkedlist
103     cout << "PrintList(pMHead)" << endl;
104     testSolution.PrintList(pMHead);
105
106     ListNode *pTarget = testSolution.FindFirstCommonNode(pMHead, pKNode);
107
108     // Print Head
109     cout << "pMHead = " << pMHead << endl;
110     if (pMHead != NULL)
111        cout << "pMHead->val = " << pMHead->val << endl;
112     cout << endl;
113
114     // Print Kth Node
115     cout << "pTarget = " << pTarget << endl;
116     if (pTarget != NULL)
117        cout << "pTarget->val = " << pTarget->val << endl;
118     cout << endl;
119
120     // Print Linkedlist
121     cout << "PrintList(pMHead)" << endl;
122     testSolution.PrintList(pMHead);
123
124     getchar();
125
126     return 0;
127 }

View Code

转载于:https://www.cnblogs.com/pegasus923/p/5574944.html

学习笔记之15道简单算法题相关推荐

  1. JAVA 判断简单密码算法_十道简单算法题二【Java实现】

    前言 清明不小心就拖了两天没更了-- 这是十道算法题的第二篇了-上一篇回顾:十道简单算法题 最近在回顾以前使用C写过的数据结构和算法的东西,发现自己的算法和数据结构是真的薄弱,现在用Java改写一下, ...

  2. 十道简单算法题二【Java实现】

    前言 清明不小心就拖了两天没更了-- 这是十道算法题的第二篇了-上一篇回顾:十道简单算法题 最近在回顾以前使用C写过的数据结构和算法的东西,发现自己的算法和数据结构是真的薄弱,现在用Java改写一下, ...

  3. 数据结构学习笔记(六)链表算法题

    假期结束,看点题目. 第一题 问题 设顺序表用数组A[]表示,表中元素存储在数组下标1~m+n的范围内,前m个元素递增有序,后n个元素递增有序,设计一个算法,使得整个顺序表有序. (1)给出算法的基本 ...

  4. java的简单算法题_[2]十道算法题【Java实现】

    前言 清明不小心就拖了两天没更了-- 这是十道算法题的第二篇了-上一篇回顾:十道简单算法题 最近在回顾以前使用C写过的数据结构和算法的东西,发现自己的算法和数据结构是真的薄弱,现在用Java改写一下, ...

  5. 惊!面试现场,简单几道java算法题,90%程序员没写出来

    近几个月很多大学实习生离校找实习工作去了,本以为自己很值钱,实际上发现自己并不值钱,想象着自己能赚很多钱了,结果只能拿到一点微薄的工资,很多人会怪公司给的少,但是你有没有想过,你自己的技术值多少钱?你 ...

  6. tensorflow学习笔记二——建立一个简单的神经网络拟合二次函数

    tensorflow学习笔记二--建立一个简单的神经网络 2016-09-23 16:04 2973人阅读 评论(2) 收藏 举报  分类: tensorflow(4)  目录(?)[+] 本笔记目的 ...

  7. python全排序算法题_Python的100道经典算法题(1)

    按照c语言的100道经典算法题,自己原创写的,就得是自己的练习题了 [程序1] 题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 程序分析:可填在百位.十位.个位的数 ...

  8. python学习笔记(15)循环设计

    python学习笔记(15)循环设计 原链:http://www.cnblogs.com/vamei/archive/2012/07/09/2582435.html 注意:zip()在python2 ...

  9. 机器学习实战(Machine Learning in Action)学习笔记————06.k-均值聚类算法(kMeans)学习笔记...

    机器学习实战(Machine Learning in Action)学习笔记----06.k-均值聚类算法(kMeans)学习笔记 关键字:k-均值.kMeans.聚类.非监督学习 作者:米仓山下 时 ...

最新文章

  1. 台3岁女童疑把玩风枪致死案疑点多 警方将调查厘清
  2. 上篇文章中ygc越来越慢的case的原因解读
  3. $.ajax使用总结(一):Form提交与Payload提交
  4. 《统计学:从数据到结论》学习笔记(part3)--任何统计量,只要人们觉得合适就可以当成估计量
  5. 一定要会的synchronized关键字的用法
  6. java创建和销毁一个对象_有效的Java –创建和销毁对象
  7. cesium(鼠标事件)
  8. 北京市委书记蔡奇:加快拓展数字人民币应用全场景试点
  9. 怎么判断浮点数的有效位数_JavaScript的数据类型及判断
  10. ARTS打卡计划第一周-Tips-ControllerAdvice的使用
  11. react实现聊天界面_React-Redux 100行代码简易版探究原理
  12. jsp 九大内置对象详解以及示例
  13. VRAR行业深度报告:VRAR是中场,Metaverse是终局
  14. ROS中使用罗技G29遥控器
  15. [信息论与编码] 03. 离散信源、信源熵、联合熵、条件熵
  16. 网上书城项目-LoadRunner压力测试
  17. C语言学习:原子操作
  18. js中submit失效
  19. linux 路由器都会断流吗,有没有迷你路由器推荐?MTK路由器经常断流..
  20. SCSI的配置全攻略(ISCSI Target/initiator)

热门文章

  1. spingbot 与 activiti 整个 中创建表而找不到表的问题(创建表失败)
  2. linux ubuntn j经验
  3. 前后端分离提交多次验证
  4. rem适配的浏览器_[史上最全]UI相关尺寸单位详解 | px、pt、dp、sp、rem、vwvh、rpx、ppi、dpi、dppx...
  5. windows防火墙设置_合理利用Windows 7防火墙,阻止部分功能,避免网络恶意软件攻击...
  6. 必须声明标量变量 @列名
  7. oracle xp 安装包资源
  8. java poi导出Excel表格超大数据量解决方案
  9. java两个栈怎么完成初始化_Spring bean初始化及销毁你必须要掌握的回调方法
  10. matlab层次分析法代码_基于主成分分析法和层次分析法的工程项目经理胜任力评价研究...