Data Structure
Remove by value from a linked list
A prev pointer pointing to the previous node than the target node is necessary
What is the time complexity of this code? n = 10 # Can be anything sum = 0 pie = 3.14 var = 1 while var < n: print(pie) for j in range(var): sum+=1 var*=2 print(sum)
A simple way to think of this would be that the running time of this piece of code actually boils down to the statement inside the for loop, i.e., sum+=1. In the first iteration of the outer loop, it is run once. In the second iteration of the outer loop, it is run twice. it is run 4 times the third time and 8 times at the fourth iteration of the outer loop. So, then, the number of times that line is run is 1 + 2 + 4 + 8 + ... + n. Which is the sum of the geometric series and comes down to 2n-1 which is in O(n)O(n).
Asymptotic Notations
Big O is less than or equal to Big Omega is greater or equal to Big Theta is in between small o is strictly less than small omega is strictly bigger than
Generating binary numbers using a Queue
Candidates are generated by appending 0 and 1 to the top of the queue, i.e. left element, then append them to the end of the queue, i.e. right side. Result list is generated by appending the top element.
Big O tips
General Tips Every time a list or array gets iterated over c \times lengthc×length times, it is most likely in O(n)O(n) time. When you see a problem where the number of elements in the problem space gets halved each time, that will most probably be in O(log n)O(logn) runtime. Whenever you have a singly nested loop, the problem is most likely in quadratic time.
Linked lists vs. Arrays
In a linked list, insertion and deletion happen in a constant amount of time. You can simply add or delete a Node between two Nodes. In an array, the two operations would take O(n) time since addition or deletion would mean shifting the whole array left or right. The access operation in arrays is much faster as you can simply use the index of an array to access the value you need. In linked lists, there is no concept of indexing. To reach a certain element in the list, we must traverse it from the beginning.
Longest substring with all distinct characters
Keep track of the last location of each charater, if there is one duplicate in the end of substring, just jump the start of the substring to the next charater of the last seen location.
List vs Array
List can store heterogeneous data types where as array cannot. However, arrays are much more efficient for storing and manipulating data.
What is the time complexity of this code? n = 10 # can be anything, this is just an example sum = 0 pie = 3.14 j = 1 for var in range(1,n,3): print(pie) while j < n: sum+=1 j*=3 print(sum)
Note that the outer loop is O(n/3) where as the inner loop is j*=3 not j+=3 j*=3 -> O(log3(n)) So the total time complexity is O(nlog3(n))
Find the second largest element in a list in one traversal
Pay attention to the first IF sentence: swap values first, then assign the new value to first. For the second IF sentence: make sure to check the value is not the same with the first in case the largest value has duplicates.
Rearrange String K Distance Apart Given a string and a number 'K', find if the string can be rearranged such that the same characters are at least 'K' distance apart from each other. Example 1: Input: "mmpp", K=2Output: "mpmp" or "pmpm"Explanation: All same characters are 2 distance apart. Example 2: Input: "Programming", K=3Output: "rgmPrgmiano" or "gmringmrPoa" or "gmrPagimnor" and a few moreExplanation: All same characters are 3 distance apart.
Use queue to push tuple back to the heap after K iterations.
Return the Nth node from the end
Watch out the edge case where N is bigger than the length of the linked list
Big O for Nested for loops
When the inner loop is varying depend on the variable of the outer loop, generally the time complicity would be O(n^2), when the inner loop is reduced by half, it would normally be O(nlogn). And when the inner is from multiply/division of the outer variable, it would be O(logn).
Longest substring with single character after replacing no more than k characters.
keep track of the most frequent char in the window. The rest of the other chars should not exceed k.
Max Subarray using sliding window
windowSum and windowStart needs to be initialized and the loop variable is windowEnd. Sub-sequential behavior is triggered when the window grows to k size.