Skip to content

Commit bc100bc

Browse files
committed
Add comments to explain the solutions
1 parent 0858fdb commit bc100bc

File tree

7 files changed

+289
-43
lines changed

7 files changed

+289
-43
lines changed

src/candy/candy.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,32 @@ using namespace std;
2525

2626
void print(vector<int> &v);
2727

28+
/*
29+
* The soluiton is O(2n) run-time complexity
30+
*
31+
* For example:
32+
*
33+
* ratings[] = { 5, 6, 7, 4, 1, 2, 3, 2, 1, 7 }
34+
*
35+
* 1) Go through the ratings from left to right.
36+
*
37+
* Find the each increasing sub-array, giving the minimal candy
38+
*
39+
* ratings[] = { 5, 6, 7, 4, 1, 2, 3, 2, 1, 7 }
40+
* ------> -> ------> -> --->
41+
* candy[] = { 1, 2, 3, 1, 1, 2, 3, 1, 1, 2 }
42+
*
43+
* 2) Go through the raings from right to left.
44+
*
45+
* ratings[] = { 5, 6, 7, 4, 1, 2, 3, 2, 1, 7 }
46+
* <- <- <------ <- <------ <-
47+
* prev_candy[] = { 1, 2, 3, 1, 1, 2, 3, 1, 1, 2 }
48+
* +1 +1
49+
* candy[] = { 1, 2, 3, 2, 1, 2, 3, 2, 1, 2 }
50+
*
51+
* 3) total candy is 19
52+
*
53+
*/
2854
int candy(vector<int> &ratings) {
2955

3056
vector<int> candyCnt(ratings.size()) ;
@@ -71,5 +97,10 @@ int main(int argc, char**argv)
7197

7298
cout << candy(ratings) << endl;
7399

100+
cout << "--------------------" << endl;
101+
int r[] = { 5, 6, 7, 4, 1, 2, 3, 2, 1, 7 };
102+
vector<int> ra(r, r+sizeof(r)/sizeof(r[0]));
103+
print(ra);
104+
cout << candy(ra) << endl;
74105
return 0;
75106
}

src/copyListWithRandomPointer/copyListWithRandomPointer.cpp

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
*
1313
**********************************************************************************/
1414

15+
16+
1517
/**
1618
* Definition for singly-linked list with a random pointer.
1719
* struct RandomListNode {
@@ -20,6 +22,50 @@
2022
* RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
2123
* };
2224
*/
25+
26+
27+
/*
28+
*
29+
* The idea as below:
30+
*
31+
* Consider we have a linked list as below:
32+
*
33+
* node1->random = node2;
34+
* node2->random = node1;
35+
* node3->random = node1;
36+
*
37+
* +-------------+
38+
* | v
39+
* +-------+ +-------+ +-------+
40+
* | node1 |----> node2 |----> node3 |--->NULL
41+
* +-------+ +-------+ +-------+
42+
* ^ ^ | |
43+
* | +-----------+ |
44+
* +--------------------------+
45+
*
46+
*
47+
* To copy the list,
48+
*
49+
* 1) We insert a new node for each node's next position
50+
*
51+
*
52+
* +-------------------------+
53+
* | v
54+
* +--+----+ +-----+ +-------+ +-----+ +-------+
55+
* | node1 |---> | NEW |----> node2 |---> | NEW |----> node3 |--->NULL
56+
* +-------+ +-----+ +---+---+ +-----+ +--+----+
57+
* ^ ^ | |
58+
* | +-----------------------+ |
59+
* +--------------------------------------------------+
60+
*
61+
* 2) Then, we can construt the new node's random pointer:
62+
*
63+
* (node1->next) -> random = (node1->random) -> next;
64+
*
65+
* 3) After we take out all of the "NEW" node to finish the copy.
66+
*
67+
*/
68+
2369
class Solution {
2470
public:
2571
RandomListNode *copyRandomList(RandomListNode *head) {
@@ -62,20 +108,57 @@ class Solution {
62108
return h;
63109
}
64110
};
65-
66-
111+
112+
113+
/*
114+
* Considering we have a link as below:
115+
*
116+
*
117+
* +-------------+
118+
* | v
119+
* +-------+ +-------+ +-------+
120+
* | node1 |----> node2 |----> node3 |--->NULL
121+
* +-------+ +-------+ +-------+
122+
* ^ ^ | |
123+
* | +-----------+ |
124+
* +--------------------------+
125+
*
126+
* 1) Using a map to store each node's random pointer's position
127+
*
128+
* map[node1->random] = 1;
129+
* map[node2->random] = 0;
130+
* map[node3->random] = 0;
131+
*
132+
* 2) Clone the linked list (only consider the next pointer)
133+
*
134+
* new1 --> new2 --> new3 --> NULL
135+
*
136+
* 3) Using an array to strore the order of the cloned linked-list
137+
*
138+
* v[0] = &new1
139+
* v[1] = &new2
140+
* v[2] = &new3
141+
*
142+
* 4) Then we can clone the random pointers.
143+
*
144+
* new->random = v [ map[node->random] ]
145+
*
146+
*/
67147
class MySolution {
68148
public:
69149
RandomListNode *copyRandomList(RandomListNode *head) {
150+
70151
RandomListNode *p = NULL, *h=NULL, *t=NULL;
71-
152+
//using a map to store the random pointer's postion.
72153
map<RandomListNode*, int> m;
73-
154+
//construct the map
74155
int pos =0;
75156
for ( p = head; p != NULL; p = p->next, pos++){
76157
m[p] = pos;
77158
}
78159

160+
//clone the linked list (only consider the next pointer)
161+
//and using a vector to store each node's postion.
79162
vector<RandomListNode*> v;
80163
for (p = head; p != NULL; p = p->next){
81164
RandomListNode *node = new RandomListNode(p->label);
@@ -88,14 +171,17 @@ class MySolution {
88171
}
89172
}
90173

174+
//p => source link head
175+
//t => new link head
176+
//move the p and t synchronously, and
177+
// t->random = vector[ map[p->random] ];
91178
for (t=h, p = head; t!=NULL && p!= NULL; p=p->next, t=t->next){
92179
if (p->random!=NULL) {
93180
pos = m[p->random];
94181
t->random = v[pos];
95182
}
96183
}
97184

98-
99185
return h;
100186

101187
}

src/longestConsecutiveSequence/longestConsecutiveSequence.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,22 @@
1515
*
1616
**********************************************************************************/
1717

18+
//
19+
// Obviously, the easist way is sort the array, however the run-time complexity is O(nlogn)
20+
//
21+
// If we cannot use the sort algorithm, then it seems we have to use O(n^2) solution.
22+
//
23+
// That's fine, let's take a look the O(n^2) soultion
24+
//
25+
// 1) for each item num[i] in the array
26+
// 2) for loop to seach ...... num[i-2], num[i-1], num[i]+1, num[i]+2 ......
27+
//
28+
// We can see, the search is really heavy, and the best data structure for seaching is HashMap.
29+
// hash map is O(1) run-time complexity for seaching.
30+
//
31+
// So, we can have the following solution by using Hash Map.
32+
//
33+
1834
class Solution {
1935
public:
2036
int longestConsecutive(vector<int> &num) {

src/palindromePartitioning/palindromePartitioning.II.cpp

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -40,44 +40,46 @@ int minCut(string s) {
4040
return minCut_DP(s);
4141
}
4242

43-
//DP
44-
4543
/*
46-
47-
Define res[i] = the minimum cut from 0 to i in the string.
48-
The result w =e need eventually is res[s.size()-1].
49-
We know res[0]=0. Next we are looking for the optimal solution function f.
50-
51-
For example, let s = "leet".
52-
53-
f(0) = 0; // minimum cut of str[0:0]="l", which is a palindrome, so not cut is needed.
54-
f(1) = 1; // str[0:1]="le" How to get 1?
55-
f(1) might be: (1) f(0)+1=1, the minimum cut before plus the current char.
56-
(2) 0, if str[0:1] is a palindrome (here "le" is not )
57-
f(2) = 1; // str[0:2] = "lee" How to get 2?
58-
f(2) might be: (1) f(1) + 1=2
59-
(2) 0, if str[0:2] is a palindrome (here "lee" is not)
60-
(3) f(0) + 1, if str[1:2] is a palindrome, yes!
61-
f(3) = 2; // str[0:3] = "leet" How to get 2?
62-
f(3) might be: (1) f(2) + 1=2
63-
(2) 0, if str[0:3] is a palindrome (here "leet" is not)
64-
(3) f(0) + 1, if str[1:3] is a palindrome (here "eet" is not)
65-
(4) f(1) + 1, if str[2:e] is a palindrome (here "et" is not)
66-
OK, output f(3) =2 as the result.
67-
68-
So, the optimal function is:
69-
70-
f(i) = min [ f(j)+1, j=0..i-1 and str[j:i] is palindrome
71-
0, if str[0,i] is palindrome ]
72-
73-
The above algorithm works well for the smaller test cases, however for the big cases, it still cannot pass.
74-
Why? The way we test the palindrome is time-consuming.
75-
76-
Also using the similar DP idea, we can construct the look-up table before the main part above, so that the palindrome testing becomes the looking up operation. The way we construct the table is also the idea of DP.
77-
e.g. mp[i][j]==true if str[i:j] is palindrome.
78-
mp[i][i]=true;
79-
mp[i][j] = true if str[i]==str[j] and (mp[i+1][j-1]==true or j-i<2 ) j-i<2 ensures the array boundary.
80-
*/
44+
* Dynamic Programming
45+
* -------------------
46+
*
47+
* Define res[i] = the minimum cut from 0 to i in the string.
48+
* The result w =e need eventually is res[s.size()-1].
49+
* We know res[0]=0. Next we are looking for the optimal solution function f.
50+
*
51+
* For example, let s = "leet".
52+
*
53+
* f(0) = 0; // minimum cut of str[0:0]="l", which is a palindrome, so not cut is needed.
54+
* f(1) = 1; // str[0:1]="le" How to get 1?
55+
* f(1) might be: (1) f(0)+1=1, the minimum cut before plus the current char.
56+
* (2) 0, if str[0:1] is a palindrome (here "le" is not )
57+
* f(2) = 1; // str[0:2] = "lee" How to get 2?
58+
* f(2) might be: (1) f(1) + 1=2
59+
* (2) 0, if str[0:2] is a palindrome (here "lee" is not)
60+
* (3) f(0) + 1, if str[1:2] is a palindrome, yes!
61+
* f(3) = 2; // str[0:3] = "leet" How to get 2?
62+
* f(3) might be: (1) f(2) + 1=2
63+
* (2) 0, if str[0:3] is a palindrome (here "leet" is not)
64+
* (3) f(0) + 1, if str[1:3] is a palindrome (here "eet" is not)
65+
* (4) f(1) + 1, if str[2:e] is a palindrome (here "et" is not)
66+
* OK, output f(3) =2 as the result.
67+
*
68+
* So, the optimal function is:
69+
*
70+
* f(i) = min [ f(j)+1, j=0..i-1 and str[j:i] is palindrome
71+
* 0, if str[0,i] is palindrome ]
72+
*
73+
* The above algorithm works well for the smaller test cases, however for the big cases, it still cannot pass.
74+
* Why? The way we test the palindrome is time-consuming.
75+
*
76+
* Also using the similar DP idea, we can construct the look-up table before the main part above,
77+
* so that the palindrome testing becomes the looking up operation. The way we construct the table is also the idea of DP.
78+
*
79+
* e.g. mp[i][j]==true if str[i:j] is palindrome.
80+
* mp[i][i]=true;
81+
* mp[i][j] = true if str[i]==str[j] and (mp[i+1][j-1]==true or j-i<2 ) j-i<2 ensures the array boundary.
82+
*/
8183

8284

8385
int minCut_DP(string& s) {

src/palindromePartitioning/palindromePartitioning.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,34 @@ bool isPalindrome(string &s, int start, int end) {
3838
return true;
3939
}
4040

41+
// DFS - Deepth First Search
42+
//
43+
// For example: "aaba"
44+
//
45+
// +------+
46+
// +------| aaba |-----+
47+
// | +------+ |
48+
// +-v-+ +-v--+
49+
// | a |aba | aa |ba
50+
// +---+---+--+ +--+-+
51+
// | | |
52+
// +-v-+ +--v--+ +-v-+
53+
// | a |ba | aba |\0 | b |a
54+
// +-+-+ +-----+ +-+-+
55+
// | a, aba |
56+
// +-v-+ +-v-+
57+
// | b |a | a |\0
58+
// +-+-+ +---+
59+
// | aa, b, a
60+
// +-v-+
61+
// | a |\0
62+
// +---+
63+
// a, a, b, a
64+
//
65+
// You can see this algorithm still can be optimized, becasue there are some dupliation.
66+
// ( The optimization you can see the "Palindrome Partitioning II" )
67+
//
68+
4169
void partitionHelper(string &s, int start, vector<string> &output, vector< vector<string> > &result) {
4270

4371
if (start == s.size()) {
@@ -46,8 +74,11 @@ void partitionHelper(string &s, int start, vector<string> &output, vector< vecto
4674
}
4775
for(int i=start; i<s.size(); i++) {
4876
if ( isPalindrome(s, start, i) == true ) {
77+
//put the current palindrome substring into ouput
4978
output.push_back(s.substr(start, i-start+1) );
79+
//Recursively check the rest substring
5080
partitionHelper(s, i+1, output, result);
81+
//take out the current palindrome substring, in order to check longer substring.
5182
output.pop_back();
5283
}
5384
}

src/wordLadder/wordLadder.II.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,40 @@
3939
#include <unordered_set>
4040
using namespace std;
4141

42+
// Solution
43+
//
44+
// 1) Using BSF algorithm build a tree like below
45+
// 2) Using DSF to parse the tree to the transformation path.
46+
//
47+
// For example:
48+
//
49+
// start = "hit"
50+
// end = "cog"
51+
// dict = ["hot","dot","dog","lot","log","dit","hig", "dig"]
52+
//
53+
// +-----+
54+
// +-------------+ hit +--------------+
55+
// | +--+--+ |
56+
// | | |
57+
// +--v--+ +--v--+ +--v--+
58+
// | dit | +-----+ hot +---+ | hig |
59+
// +--+--+ | +-----+ | +--+--+
60+
// | | | |
61+
// | +--v--+ +--v--+ +--v--+
62+
// +----> dot | | lot | | dig |
63+
// +--+--+ +--+--+ +--+--+
64+
// | | |
65+
// +--v--+ +--v--+ |
66+
// +----> dog | | log | |
67+
// | +--+--+ +--+--+ |
68+
// | | | |
69+
// | | +--v--+ | |
70+
// | +--->| cog |<-- + |
71+
// | +-----+ |
72+
// | |
73+
// | |
74+
// +----------------------------------+
75+
4276
map< string, unordered_set<string> >&
4377
buildTree(string& start, string& end, unordered_set<string> &dict) {
4478

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy