0% found this document useful (0 votes)
29 views

Leetcode 75

leetcode
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views

Leetcode 75

leetcode
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 6

String:

Valid Parathenses: Use stack.


If ( { [, push
If ) ] }
- But stack empty, return false
- But s.top() is not ) ] } accordingly, return false
else s.pop();
In the end, if !s.empty(), return false

Valid Palindrome: Input: s = "A man, a plan, a canal: Panama"


Output: true
Explanation: "amanaplanacanalpanama" is a palindrome.
-> Solution: traverse inside a while/for loop with condition right > left, be
careful! This is not easy as it seems.

468. Valid IP Address:


- Write a split function return parts: vector<string> split(string & s)
- Bool isIPv4:
+ if parts.size != 4, return false.
+ if (part.empty() || part.size() > 3 || part.size() > 1 && part[0] ==
'0') // check leading 0s
+ for (auto i : part) if !isdigit return false
+ if (stoi(part) > 255) return false
- Bool isIPv6:
+ if parts.size() !8 return false
+ if (part.empty() || part.size() > 4) return false
+ for (auto i : part) if !isxdigit return false

Valid anagram: Use array of 75, (int)s[i] - 48, O(n), O(75). Or use unordered_map
for universal unicode, check for 0, O(n), O(n) values.

firstNonRepeatingCharacter: "abcab" -> 'c', "abcabc" -> '_'. Solution: Use hash to
store key: char, value: freq, position to avoid O(2N) looping, but O(3N) data
structure. Or: Use array[26]. 'a'- 98 = 0.

Word Ladder I: Input: beginWord = "hit", endWord = "cog", wordList =


["hot","dot","dog","lot","log","cog"]
Output: 5
Explanation: One shortest transformation sequence is "hit" -> "hot" -> "dot" ->
"dog" -> cog", which is 5 words long.
-> Solution: Use BFS. Trick: Calculate size of queue, use for loop for that
size (this keep the level constant without having to store level somewhere else).
Use for (char c='a';c<=z;c++) to loop characters. O(M*26*N)

Longest Repeating Character:


-> // Solution O(26n)
// Keep a sliding window (l,r). If the length of sliding window r-l+1 minus
maximum frequency of a word is less
// than k (this means we can still replace), we expand window to the right: r+
+. Else, shirnk window by increasing
// left: l++. The maximium frequency is calculating by just looping a[26].
a[26] store frequency of chars in sliding
// window. When handling increment, if r++ then we add next char, calculating
curMax, if l++ then we dont do that.
-> // Solution O(n): To avoid looping a[26], the maximium frequency is
calculating by maxF = max(maxF, frequency of current word just being modified),
because length of current word r-l+1 - maxF <= k if maxF is always valid. If
frequency increase, we update it. If frequency decrease, we don't care.
394. Decode String:
-> Stack: ...
-> Recursion: string helper(int & pos, const string & s)
- If see '[', helper subproblem, then add num times the repeatedString
to word
- If see ']', return word
- If see digit >= '0' && <= '9', add to num: num = num*10 + s[pos] -'0'
- If see regular characters, add to word
- Return word;

Valid Parenthesis String 678:


-> Greedy, counting balance both max and min. Max is when * = (, min is *
= ).
- If high < 0, return false (unpaired close parenthesis)
- low = max(low, 0), can't have negative number of ), so * = "" instead
- return if low == 0 or not.

Group Anagram:
-> Solution 1: O(N*K*26): key is "98979797979710097....97" represent "aggg"
value is the string itself
-> Solution 2: O(N*K*log(K)): counting sort. Sort words then keep track of
similar group

1209. Remove adjacent duplicates in string


-> O(N): Stack
- Stack of pair <int, char>. Int is the number of times when we use append.
char is character
- loop through string s
+ if stack.top() != c, stack.push(1,c)
+ else stack.top().first++;
if st.top().first == k; st.pop();
- // appending: for (auto & p: st) res.append(p.first, p.second)

Array:
Contains Duplicate: Just use unordered_set ffs. JESUS CHRIST
Two Sum: Use unordered_map as inserting nums[i], if m.count(target - nums[i])
appear in map, we found a solution O(n), O(n)
Using two pointer make it O(n), O(1).

Maximum Sum Subarray: Single loop, 2 global var: maxSum and cur. If we come up a
new number, curSum = max(curSum +nums[i], nums[i]), then compare maxSum =
max(curSum, maxSum). The idea is: Once we come up to a number, see if we want to
add it, or we want to start over at that number. The checkpoint is a negative value

Maximum Product Subarray: Same idea as maximum sum subarray. But we have another
check: 0. 0 turns separate arrays into chunks. negative value flips the minimum to
maximum. So we need to keep check of curMin as well. Single loop, keep track of 3
global var: maxSum, curMax, curMin.
- tmp = curMax (we store this for curMin calculation, since curMax change)
- curMax = max({nums[i], nums[i]*curMax, nums[i]*curMin})
- curMin = min({nums[i], nums[i]*tmp, nums[i]*curMin})
- maxSum = max({maxSum, curMax, curMin}) // THen return maxSum in the end of
function.

Subsets I (Leetcode 78): [] [1] -> [] [1] [] [1] -> [] [1] [2] [1,2]. So the
algorithm is nested loop. Outer loop keep track of new element (nums[i]). Inner
loop do 2 things: mimic & double the res size, add new element to the half (mimic)
size of the res. Repeat.
Subsets II: the formula: j = repeatCount/(repeatCount+1). This start the new mimic
portion, works for 0
[1,2,2]: [] [1] [2] [1,2] -> [] [1] [2] [1,2] [2] [1,2] -> [] [1] [2] [1,2]
[2,2] [1,2]
[1,2,2]: [] [1] [2] [1,2] [2,2] [1,2] -> [] [1] [2] [1,2] [2,2] [1,2] [2,2]
[1,2] -> [] [1] [2] [1,2] [2,2] [1,2] [2,2,2] [1,2,2,2]

Move Zeroes: Give array, move all 0s to the right, keep everything in order
-> Solution: Partitionning algorithm (usually used in quick sort, ..) (MUST
KNOW THIS)
- Initialize left = 0; then make a forloop i from 0 to container.size()
- If the condition of the left side satisfies, swapValue(left, i), then left+
+
-> Solution 2: Smart ass but simple
- Record index of last time we see a non-zero: lastIndex
- Loop from i to container.size, if see non-zero, swap(nums[i],
nums[lastIndex]), lastIndex++;
- Later on, loop again from lastIndex to end, fills with 0s.

723. Candy Crush:


-> O((RxC)^2)
- 2 loop to get every single square. Find matching here, change it to negative
numbers (visited)
- Drop down: Do partition algorithm, 1 left pointer + 1 for loop. Swap left vs
currentIndex if number > 0

Linked List:
Reverse Linked List: Just becareful with operations. Use pre, head and cur.
Reassign head at the end. O(n), 1

QUEUE:
994. Rotting Oranges: Multi source BFS. Initialize level = 0. Remember: Inside
while (!q.empty()), save q.size() first before iterating thorugh level. q.pop() &
q.front() inside for loop that is inside while loop. Near the end of while loop,
check if current queue size: q.size() > 0, increase level.

Maximum Sliding Window:


- Sol1: priority queue, code short & simple, but O(NlogN)
- Sol2: deque, more complex but O(N). Monotonic queue problem, queue always
store decreasing order. Front is always maximum. After every loop, pop front. If
encounter greater element than front, pop everything.

Graph:
Number of Island: Loop each index of 2d-array, use BFS on an island, mark visited
(either in place or new array). O(m.n), O(m.n)

Binary:
Reverse Bits: Tricks: Get the ith digits: digit = n>>i & 1; adding digits to the
end: a*2 + digit; or a<<1 + digit. O(n)
Missing numbers: Trick: XOR same number gets 0, XOR 0 with a number get a number.
So XOR everything together, meaning nums[i] ^ i (i from 1 to n) then XOR res^n give
you the result. Other solution is just do n(n+1)/2 - sum(nums[i from 0 to size]) =
res.

Matrix:
Rotate Image:
Method 1: Do spiral interval, shift a row to column, store the placement
value first though.
Method 2: Do a transpose, then do a reverse (horizontally or vertically)
depends on flip 90 clockwise or cc.

Recursion:
Merge Sort: Divide array by 2, base case is array size = 1, then merge the two sub-
array.

93. Restore IP address: Recursion exhaustive search.

Tree:
Invert Binary tree: DFS, change left to right, recursive root->left, recursive
root->right, return root

K-smallest element in BST: , k global (by reference), when k == 0, save Res global.

When done, return res. Modify the function call to pass by reference.

Maximum Depth of Binary Tree: return 1 + max(maxDepth(left), maxDepth(right))

Same Tree: if (!p & q) || (!q && p) return false; if (!p && !q) return true;
else return p->val == q->val && isSameTree(p->left, q->left) && isSameTree(p-
>right, q-right)
Subtree of Another Tree:
O(NxM): traverse O(N), check for everynode isSametree O(M). O(NxM)

Binary Tree Level Order Traversal: Queue


Binary Tree zigzag Print: Push to queue, pop from queue to stack, then print.

Trie (Prefix Tree):


- Constructor (Root, children[26], isEndOfWord)
- Insert(Node*root,string word): Loop through word, if (!cur-
>children[indexWord]) construct word, else cur = cur-
>children[indexWord]. At the end, cur->isEndOfWord = true
- searchWord(Node*root,string word): Loop through word, if (!cur-
>children[indexWord]) return false, else cur = cur->children[indexWord]. At
the end, return cur && cur->isEndOfWord

Construct Binary Tree from Preorder & Inorder:


// Key idea: Root is always first in preorder, find the subleft, subright in
both preorder and inorder array, then do recursive call to construct root->left &
root->right.
-> Elegance solution O(N^2):
// first we find root in inorder, call it mid
// Then construct arrays: subarrayPreLeft, subarrayPreRight, subarrayInLeft,
subArrayInRight
// Then construct root->left = buildTree(subarrayPreLeft, subarrayPreRight),
same for root->right
// Then return root.
-> Efficient solution O(N): (A LOT OF indexing and then recursive)
// Root is always first in preorder, find the subleft, subright in both
preorder and inorder array
// First, find index of root in inorder, call it mid
// Then divide subleft and subright (in preoreder and inorder) correctly based
on that index:
// preLeft start at: preLeft + 1, ends at preLeft + mid - inLeft;
// inLeft start at: inLeft, ends at mid - 1;
// preRight start at: preLeft + mid - inLeft + 1;
// inRight start at: mid + 1, ends at inRight;
// Then call root->left = helper(preorder, inorder, preSubLeftIndex,
preSubRightIndex, inSubLeftIndex, inSubRightIndex) and root->right ... accordingly

98. Valid Binary Search Tree:


- Iterative: In order traversal. The output is sorted increasing
- Recursion: Keep track of minNode & maxNode, compare root only, very simple
- If minNode > root->val, return false. If maxNode < root->val, return
false;
- If traverse left, maxNode = root, minNode = minNode
- If traverse right, minNode = root, maxNode = maxNode

BackTrack
79. Word Search:
-> O(R*C * 4*(3^L)) dfs backtrack solution. R=row, C=col, L=word.length().
3^L b/c we dont go back to visited node. 4*(3^L) because 4 directions.
- For(rows) for(cols), if (dfs(board, word, rows, col, 0)) return true
// Sub problem start at 0 index of word.
- If (pos == word.size()) return true; // Base case, found match
- If out of bound, return false; // Out of Bound
- If (board[row][col] != word[pos]) return false; // We dfs but at this
point there's no matching word
- else we OR the result of dfs(4directions) to bool furtherSearch search
while marking current one visited.
- At the end, mark current one back to original: board[row][col] = word[pos];
then return furtherSearch;

1415. The k-th Lexicographical String of All Happy Strings of Length n:


-> O(n*k): dfs backtrack + early terminate
- Maintain current string (for push, pop), global res for return, global
count to keep track of recursion
- If n == 0, if count == 0, res = cur, return;
- Loop through wordList = {a, b, c} except for value s.back()
- cur.push_back(wordList[i]); helper(n-1,count,cur,res); cur.pop_back()
//push at begin, pop at end

91. Decode Ways:


-> O(2^N): decision tree of 2 branch, taking 1 digit or 2 digits
- int backtrack(p, string& s)
- base case: index p = s.size , return 1(finish a string, add 1 to
count)
- base case: s[p] = '0' , return 0 (Can't decode starting with 0)
- int res = backtrack(p+1,s)
- if (taking 2 digits is valid), res += backtrack(p+2,s)
return res;

DP:
55. Jump Game I:
-> O(N^N): if pos == nums.size() - 1, flag = true. For (i in len), dfs(nums,
pos+i).
->
-> // O(N) greedy solution:
// Calculate from the end. If the i^th position can reach the goal, update
goal.
// Return goal == 0 // This means we can reach the final destination from
the beginning

You might also like

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