Skip to content

Commit b3c370f

Browse files
More leetcode
1 parent 0d1857d commit b3c370f

File tree

2 files changed

+268
-4
lines changed

2 files changed

+268
-4
lines changed

Interview/Algorithm/LeetCode_for_embedded_advanced.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1471,4 +1471,4 @@ public:
14711471
return cur;
14721472
}
14731473
};
1474-
```
1474+
```

Interview/Algorithm/algorithm_prepare.md

Lines changed: 267 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
17. [Subarray Sum Equals K](#Subarray-Sum-Equals-K) Medium
2020
18. [Find the Kth largest item](#Find-the-Kth-largest-item) Medium
2121
19. [Count Duplicates](#Count-Duplicates) Medium
22-
20. [3 Sum](#3-Ssum)
23-
21. [Majority Item](Majority Item) Medium
22+
20. [3 Sum](#3-Ssum) Medium
23+
21. [Majority Item](#Majority-Item) Medium
2424

2525
## Matrix
2626
1. [Diagnose Tranverse](#Diagnose-Tranverse) Medium
@@ -56,6 +56,9 @@
5656
1. [Valid Anagram](#Valid-Anagram) Easy
5757
2. [Integer to English Words](#Integer-to-English-Words) Hard
5858
3. [Insert five](#Insert-five) Easy
59+
4. [Partition Labels](#Partition-Labels) Medium
60+
5. [Longest Palindromic Substring](#Longest-Palindromic-Substring) Medium
61+
6. [Word Break](#Word-Break) Medium
5962

6063
## Bits Manipulation
6164
1. [Is Power of Four](#Is-Power-of-Four) Easy
@@ -66,6 +69,7 @@
6669
## Data Structure
6770
1. [LRU cache](#LRU-cache) Hard
6871
2. [LFU cache](#LFU-cache) Hard
72+
3. [Min Stack](#Min-Stack) Easy
6973

7074
## OS flavor
7175
1. [Task Scheduler](#task-scheduler) Medium
@@ -89,6 +93,7 @@
8993
13. [Container With Most Water](#Container-With-Most-Water) Medium
9094
14. [Move Zeroes](#Move-Zeroes) Medium
9195
15. [Symmetric Tree](#Symmetric-Tree) Easy
96+
16. [Subtree of Another Tree](#Subtree-of-Another-Tree) Medium
9297

9398
## Implementation
9499

@@ -1363,7 +1368,7 @@ private:
13631368

13641369
string tens[10] = {"", "Ten ", "Twenty ", "Thirty ", "Forty ", "Fifty ", "Sixty ", "Seventy ", "Eighty ", "Ninety "};
13651370

1366-
pair<int, string> units[4] = {{1000*1000*1000, "Billion "}, {1000*1000, "Million "}, {1000, "Thousand "}, {100, "Hundred "}};
1371+
pair<int, string> units[4] = { {1000*1000*1000, "Billion "}, {1000*1000, "Million "}, {1000, "Thousand "}, {100, "Hundred "}};
13671372
};
13681373
```
13691374
### **Reorder list**
@@ -3138,4 +3143,263 @@ public:
31383143
return ans;
31393144
}
31403145
};
3146+
```
3147+
3148+
### Partition Labels
3149+
***Big O:*** O(N) speed, O(1) space
3150+
```
3151+
Tips:
3152+
3153+
First record all the last occurance indexes of each letter. Than go through the array again and partition.
3154+
```
3155+
```c++
3156+
class Solution {
3157+
public:
3158+
vector<int> partitionLabels(string S) {
3159+
int letters[26] = {0};
3160+
int n = S.size();
3161+
vector<int> ans;
3162+
3163+
if (n == 0)
3164+
return ans;
3165+
3166+
for (int i = 0; i < n; i++) {
3167+
// record the last occurance index of the letter
3168+
letters[S[i]-'a'] = i;
3169+
}
3170+
3171+
int p_size = letters[S[0]-'a'];
3172+
for (int i = 0; i < n; i++) {
3173+
// record the last occurance index of the letter
3174+
if (i <= p_size) {
3175+
p_size = max(letters[S[i]-'a'], p_size);
3176+
} else {
3177+
ans.push_back(p_size);
3178+
p_size = letters[S[i]-'a'];
3179+
}
3180+
}
3181+
ans.push_back(p_size);
3182+
3183+
for (int i = ans.size()-1; i >= 1; i--) {
3184+
ans[i] = ans[i] - ans[i-1];
3185+
}
3186+
ans[0] += 1;
3187+
3188+
return ans;
3189+
}
3190+
};
3191+
```
3192+
3193+
### Longest Palindromic Substring
3194+
***Big O:*** O(N^2 or N^3) speed, O(1) space
3195+
```
3196+
Tips:
3197+
3198+
DP method:
3199+
3200+
To improve over the brute force solution, we first observe how we can avoid unnecessary re-computation while validating palindromes. Consider the case "ababa". If we already knew that "bab" is a palindrome, it is obvious that "ababa" must be a palindrome since the two left and right end letters are the same.
3201+
3202+
p(i, j) if substring Si...Sj is panlidrome.
3203+
3204+
Therefore:
3205+
3206+
p(i, j) = (p(i+1, j-1) && Si == Sj)
3207+
3208+
Base cases:
3209+
3210+
p(i, i) = true
3211+
p(i, i+1) = (Si == S_(i+1))
3212+
```
3213+
```c++
3214+
//Brutal Force
3215+
class Solution {
3216+
public:
3217+
bool isPanlidrome(string &s, int st, int end) {
3218+
while (st < end) {
3219+
if (s[st++] != s[end--])
3220+
return false;
3221+
}
3222+
3223+
return true;
3224+
}
3225+
3226+
string longestPalindrome(string s) {
3227+
int n = s.size();
3228+
string ans = "";
3229+
3230+
for (int i = 0; i < n; i++) {
3231+
int st = i, end = n-1;
3232+
while (st <= end) {
3233+
// if it is guanranteed that ans has bigger size, go to the next index
3234+
if ((end - st + 1) <= ans.size()) {
3235+
break;
3236+
} else if (s[st] == s[end]){
3237+
if (isPanlidrome(s, st, end)) {
3238+
ans = s.substr(st, end-st+1);
3239+
}
3240+
} else {
3241+
end --;
3242+
}
3243+
}
3244+
}
3245+
3246+
return ans;
3247+
}
3248+
};
3249+
3250+
// DP solution
3251+
string longestPalindrome(string s) {
3252+
const int n = s.size();
3253+
if(n==0) return "";
3254+
int dp[n][n], maxlen =1 , left=0;// maxlen = 1 when only one word
3255+
memset(dp,0,n*n*sizeof(int));
3256+
for(int i=0;i<n;++i){
3257+
dp[i][i] = 1;
3258+
for(int j=0;j<i;++j){
3259+
dp[j][i] = (s[j]==s[i] && (i-j< 2 || dp[j+1][i-1]));
3260+
if(dp[j][i] && maxlen < i-j+1){
3261+
left = j;
3262+
maxlen = i-j+1;
3263+
}
3264+
}
3265+
}
3266+
return s.substr(left,maxlen);
3267+
}
3268+
```
3269+
3270+
### Subtree of Another Tree
3271+
***Big O:*** O(M*N) speed, O(1) space
3272+
```
3273+
Tips:
3274+
3275+
Recursion
3276+
```
3277+
```c++
3278+
class Solution {
3279+
public:
3280+
bool helper(TreeNode* s, TreeNode* t) {
3281+
if (s == nullptr && t == nullptr)
3282+
return true;
3283+
3284+
if ((s == nullptr && t != nullptr) || (s != nullptr && t == nullptr))
3285+
return false;
3286+
3287+
return s->val == t->val && helper(s->left, t->left) && helper(s->right, t->right);
3288+
}
3289+
3290+
bool isSubtree(TreeNode* s, TreeNode* t) {
3291+
if ((s == nullptr && t != nullptr) || (s != nullptr && t == nullptr))
3292+
return false;
3293+
3294+
if (helper(s, t))
3295+
return true;
3296+
3297+
return isSubtree(s->left, t) || isSubtree(s->right, t);
3298+
}
3299+
};
3300+
```
3301+
3302+
### Min Stack
3303+
***Big O:*** O(M*N) speed, O(1) space
3304+
```
3305+
Tips:
3306+
3307+
In the stack, store the pair of <new_val, current_min>.
3308+
```
3309+
```c++
3310+
class MinStack {
3311+
stack<pair<int, int>> data;
3312+
3313+
public:
3314+
/** initialize your data structure here. */
3315+
MinStack() {
3316+
3317+
}
3318+
3319+
void push(int val) {
3320+
int min_val = (val < getMin()) ? val : getMin();
3321+
data.push(make_pair(val, min_val));
3322+
}
3323+
3324+
void pop() {
3325+
if (!data.empty())
3326+
data.pop();
3327+
}
3328+
3329+
int top() {
3330+
pair<int, int> item = data.top();
3331+
return item.first;
3332+
}
3333+
3334+
int getMin() {
3335+
if (data.empty())
3336+
return INT_MAX;
3337+
3338+
pair<int, int> item = data.top();
3339+
return item.second;
3340+
}
3341+
};
3342+
```
3343+
3344+
### Word Break
3345+
***Big O:*** O(2^n or n^3) speed, O(1) space
3346+
```
3347+
Tips:
3348+
3349+
To optimize the brutal force method, we add memorizations:
3350+
3351+
In the previous approach we can see that many subproblems were redundant, i.e we were calling the recursive function multiple times for a particular string. To avoid this we can use memoization method, where an array memomemo is used to store the result of the subproblems. Now, when the function is called again for a particular string, value will be fetched and returned using the memomemo array, if its value has been already evaluated.
3352+
3353+
With memoization many redundant subproblems are avoided and recursion tree is pruned and thus it reduces the time complexity by a large factor.
3354+
```
3355+
```c++
3356+
// Brutal Force
3357+
class Solution {
3358+
public:
3359+
bool wordBreak(string s, vector<string>& wordDict) {
3360+
set<string> word_set(wordDict.begin(), wordDict.end());
3361+
return wordBreakRecur(s, word_set, 0);
3362+
}
3363+
3364+
bool wordBreakRecur(string& s, set<string>& word_set, int start) {
3365+
if (start == s.length()) {
3366+
return true;
3367+
}
3368+
for (int end = start + 1; end <= s.length(); end++) {
3369+
if (word_set.find(s.substr(start, end - start)) != word_set.end() and
3370+
wordBreakRecur(s, word_set, end)) {
3371+
return true;
3372+
}
3373+
}
3374+
return false;
3375+
}
3376+
};
3377+
3378+
// Recursion with memo
3379+
class Solution {
3380+
public:
3381+
bool wordBreak(string s, vector<string>& wordDict) {
3382+
set<string> word_set(wordDict.begin(), wordDict.end());
3383+
// In the memo table, -1 stands for the state not yet reached,
3384+
// 0 for false and 1 for true
3385+
vector<int> memo(s.length(), -1);
3386+
return wordBreakMemo(s, word_set, 0, memo);
3387+
}
3388+
3389+
bool wordBreakMemo(string& s, set<string>& word_set, int start, vector<int>& memo) {
3390+
if (start == s.length()) {
3391+
return true;
3392+
}
3393+
if (memo[start] != -1) {
3394+
return memo[start];
3395+
}
3396+
for (int end = start + 1; end <= s.length(); end++) {
3397+
if (word_set.find(s.substr(start, end - start)) != word_set.end() and
3398+
wordBreakMemo(s, word_set, end, memo)) {
3399+
return memo[start] = true;
3400+
}
3401+
}
3402+
return memo[start] = false;
3403+
}
3404+
};
31413405
```

0 commit comments

Comments
 (0)