Blind 75 + NeetCode easies

Pataasin ang iyong marka sa homework at exams ngayon gamit ang Quizwiz!

3Sum Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0. Notice that the solution set must not contain duplicate triplets.

Sort the input array to avoid reusing the same element twice then have left and right pointer in the remaining; if left and right add to 0 but if not decrease sum by shifting right pointer left (decreaes sum because array is sorted) if sum is too small shift left pointer is right → in either case shift pointer again if a variable is reused Time complexity: O(n log n) bc sorting + O(n^2) bc 2 nested loops = O(n^2) Space: O(1) O(n) iterate through index and value by doing i, a in enumerate(nums) continue if same values as before two pointer solution (left, i + 1, right len(nums ) - 1 i.e. length of lists) each value can only have one value that allows it to reach 0

Single Number Given a non-empty array of integers nums, every element appears twice except for one. Find that single one. You must implement a solution with a linear runtime complexity and use only constant extra space.

Use XOR; XOR all the input values and the result is going to be that single value because when you XOR two values that are the same you get 000 (010 COR 010 000) so everything will be canceled out except that on value because XOR can be done in any order

Maximum Depth of a Binary Tree Given the root of a binary tree, return its maximum depth. A binary tree's maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. RECURSIVE DFS

base case: return 0 if root is null recursive step: 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))

Unique Paths 2D dynamic programming There is a robot on an m x n grid. The robot is initially located at the top-left corner (i.e., grid[0][0]). The robot tries to move to the bottom-right corner (i.e., grid[m - 1][n - 1]). The robot can only move either down or right at any point in time. Given the two integers m and n, return the number of possible unique paths that the robot can take to reach the bottom-right corner.

define last value (finish) as 1 define every value out of bounds as 0 Approach: Start from the end square. Calculate how many ways there are to get to the end square from the end square (1). Then calculate how many ways there are to the end square from all adjacent squares by adding the ways to get there from the right square and botto square (since you can only move right or down). Fill up the entire chart with thai and when you get to the start you'll have all the ways to get to the end from the beginning. row → initially the bottom row (n = length of # rows); do row = [1] * n since bottom row initially 1 since can only go right go through other rows except last one (m - 1): 1. compute new row above old row [1] * n 2. to avoid edge case of checking out of bounds, go through every position except irghtmost column (last valu ein each row) is always going to be one) 3. so start at second to last position, keep going until beginning, and go in reverse order 4. newRow[j] = newRow[j +1] + row[j] (value to right and value in row below) → computes new row 5. now row is set to newRow eventually you'll get the top row return first value row[0]

Neetcode solution valid anagram (just to look at)

good to be aware of countS.get(s[i], 0) type stuff

Reverse Linked List (recursive)

this is a worse oslution

Jump Game You are given an integer array nums. You are initially positioned at the array's first index, and each element in the array represents your maximum jump length at that position. Return true if you can reach the last index, or false otherwise.

we can do greedy and reach O(N) solution start from end and see if you can reach the end we verify 1 can reach the end position → make 1 the new goalpost we see that the number before that (1) can reach the end position → make that 1 the new goal post see the number before that (3) can reach end position → make 3 the new goal post see the number before that (2) can reach the end position → make that the new goal post but its the first element so → True

Longest Palindromic Substring

what is longest palindrome with character x as the center consider character at the center and expand outwards left and right need to check even ones as a special case (otherwise we wont get them; you need to expand outwards from 2 as well) left/right pointers to i make sure l/r are inbound and it's a palindrome then update result and max length so far if length of the palindrome is greater than current result length then update left and right pointers even length is basically the same

Contains Duplicate Given an integer array nums, return true if any value appears at least twice in the array, and return false if every element is distinct.

Brute force would be O(n^2) → comparing first number against every other number and so on for every number which is O(n) for each number. Space would be O(1) because no memory used If we sorted the input any duplicates would be adjacent so to detect duplicates only need to iterate through the array once comparing 2 neighbors in the array, then comparing next 2 neighbors, and so until you finish the entire array. O(n log n) time complexity, o(1) space complexity We could use extra memory by using a HashSet, which will allow us to insert elements into the HashSet in O(1) and ask if a certain value exists. While adding values into the HashSet, before inserting an element, if we check if the value already exists, and if it does it's a duplicate. Each operation is O(1) and we do it for each element once so the time complexity is O(n). The space complexity will be O(n) since the memory used by it is up to the size of the input array; this is about as efficient as we can get

Palindromic Substrings Given a string s, return the number of palindromic substrings in it. A string is a palindrome when it reads the same backward as forward. A substring is a contiguous sequence of characters within the string.

Brute force: manually go through each substring and check if it's a palindrome with two pointers moving inwards Go through all substrings of which character is the middle position; check if left and right are equal and if so you found a new palindrome; if you get something that dosent work you know nothing more expanded to left and right is a palindrome (likewise if you go out of bounds) but you're only getting palindromes of odd left if you expand left/right simultaneously; to get the even ones (length of 2) you need to start even positions for example substring of aa then expand outwards; instead of left/right starting at the same position right = left + 1 and as long as they're equal you can expand outwards you just keep doing that for every pair of adjacent characters expanding those left/right outwards to get the even length ones Time complexity:O(n*n) = O(n^2) iterating through array for every character in array

Binary Tree Level Order Traversal Given the root of a binary tree, return the level order traversal of its nodes' values. (i.e., from left to right, level by level).

BFS is the algorithm that can do this level order Run BFS on tree and add values into lists (need to know how to implement BFS) - Need queue data structure because need FIFO - Add first element to queue to initialize queue. 1 element in queue so remove that 1 element and add it to sublist - Now queue is empty so we know sublist is complete which means we completed the first level - After popping 3, need to add its children to the queue from left to right - Now do the same and pop the two elements and add to sublist (and remember if any have children you need to add kids after popping) so on. know you're done when queue is empty Time complexity : O(N) visiting each node 1x Memory complexity : O(N) queue bc queue can hae at most n/2 elements Initialize queue with collections.deque() pop with .popleft() add with. append()

Longest Consecutive Sequence (NEETcode solution to look over)

Convert list into set so you can do O(1) operations Keep track of longest sequence seen so far Iterate number by number in the list of numbers, and go into a new sequence if (n-1) does not exist While loop to keep increasing length as long as (n + length) exists in set Finally at the end of new sequence if block, calculate longest by taking longest = max(length, longest)

Spiral Matrix Given an m x n matrix, return all elements of the matrix in spiral order

Do the outer layer first then do the same thing in the smaller subproblem Use L and R pointers; when L and R overlap you're done When you finish the top row you can shift the top boundary down since you don't need it there anymore Likewise when you finish the bottom right element you can shift the right boundary leftward since you don't need it there anymore Likewise when you finish the bottom row you can shift the bottom boundary up Time complexity: O(m*n) Memory complexity: O(1) Can stop algorithm once l, r cross

House Robber II You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have a security system connected, and it will automatically contact the police if two adjacent houses were broken into on the same night. Given an integer array nums representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police.

Basically same as first one except the first house and last house are also adjacent Run House robber 1 on the entire function except the last value and on the entire function except the first value because we're not allowed to run the first and the second function tougher. Just call the helper function on these two subarrays and whichever one is the max is the max Time complexity: O(N) Memory complexity: O(1) edge case: if array has only one element need to make sure you include max nums[0] so in that case you dont get 0 remember in functions in python you have to put self as one of the first parameters

Find Minimum In Rotated Sorted Array Suppose an array of length n sorted in ascending order is rotated between 1 and n times. For example, the array nums = [0,1,2,4,5,6,7] might become: [4,5,6,7,0,1,2] if it was rotated 4 times. [0,1,2,4,5,6,7] if it was rotated 7 times. Notice that rotating an array [a[0], a[1], a[2], ..., a[n-1]] 1 time results in the array [a[n-1], a[0], a[1], a[2], ..., a[n-2]]. Given the sorted rotated array nums of unique elements, return the minimum element of this array. You must write an algorithm that runs in O(log n) time.

Binary Search Algorithm → O(log n) [review binary search] Take left, right, and middle pointer Look at middle Search left or right? → since array is rotated left and right portion are sorted, The question is the middle in left or right sorted portion? If in left portion, want to search the right portion since if we rotated the array, the left portion would have values greater than the left sorted portion [when you rotate the vlaues on right become smaller] To determine ifyou're in the left sorted portion: * Every value in the right sorted portion will be smaller than those in the left sorted portion * Check if current middle value is greater than or equal to value all the way to the left THEN the middle value is a part of the left sorted portion, in which case w want to search to the right * IF it's false, that means we're in the right sorted portion and we need to search the left This algorithm only works on a rotated sorted array nums[m] >= nums[l] search right → move pointer all the way to 1 more than the middle else search left → move pointer to 1 less than middle

Counting Bits Given an integer n, return an array ans of length n + 1 such that for each i (0 <= i <= n), ans[i] is the number of 1's in the binary representation of i. Example 1: Input: n = 2 Output: [0,1,1] Explanation: 0 --> 0 1 --> 1 2 --> 10

Brute Force; Given integer n, Do % 2; that's the number of 1's in the first one Then do integer division and find %2 of that; that's the number of 1's in the next one And so until you reach 0 bc there's nothing more you can get of it n log n Optimal solution is O(N) pattern: 1 + dp[n - 4]. For each value, 1 + dp[n - integer] is going to be the solution. integer is the offset. offset is the most significant bit you've reached so far offset: [1, 2, 4, 8, 16] doubling in size every time The iff statement basically says: if offset * 2 is equal to i, that means the thing we're now at is the new offset because it's double the previous offset and the dp[i] statement is just the pattern we observed which you can just memorize

Same Tree Given the roots of two binary trees p and q, write a function to check if they are the same or not. Two binary trees are considered the same if they are structurally identical, and the nodes have the same value.

DFS → recursion based way to traverse trees Base case 1: Null = Null → same tree Base case 2: First tree is null, second is not -> false Base case 3: If neither are null, if the values are same it's true, otherwise false Recusirve case: return true/false of calling both of these functions on the left and right subtrees Time complexity: size of both trees added to gether O(p + q)

Balanced Binary Tree Given a binary tree, determine if it is height-balanced . A height-balanced binary tree is a binary tree in which the depth of the two subtrees of every node never differs by more than one.

Do a bottoms-up approach → dfs While determining if left/subtrees are balanced, maintain the height at each node so that you can get from each node the height of the tree so far (height at every point is going to be 1 + max(left, right) where 1 comes from node itself). Ultimately when back at the root you'll be able to compare the height of the left and right to determine if that node is balanced return true/false is subtree balanced and height of subtree

Lowest Common Ancestor of a Binary Search Tree Given a binary search tree (BST), find the lowest common ancestor (LCA) node of two given nodes in the BST. According to the definition of LCA on Wikipedia: "The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself)."

Important insights: 1. BST: left subtree <= root, right subtree >= root 2. When there's a split between the two nodes, that's the lowest common ancestor (LCA) 3. Time complexity: O(log n) because only need to visit 1 node for each level in the tree Memory complexity: O(1) since no data structures used If both the values are higher than the current node, go down right subtree If both the values are less than the current node, go down left subtree If either 1. one value is higher the other is less → split 2. one of the values is equal to the node → no other LCA possible return the current node since this is the LCA (in while loop as long as cur isnt null)

Container with Most Water You are given an integer array height of length n. There are n vertical lines drawn such that the two endpoints of the ith line are (i, 0) and (i, height[i]). Find two lines that together with the x-axis form a container, such that the container contains the most water. Return the maximum amount of water a container can store. Notice that you may not slant the container.

Find biggest area a container can form Brute force: O(N)^2; check every left pointer with every right pointer DONT DO THIS just so illustrate area = ( r - l) → that's the width min(height[l], height[r]) → take minimum of their heights bc if we take the taller ones height the smaller one wont be covered Optimal Solution O(N) algorithmic complexity Initialize left pointer t the left and right pointer to the right because you want to maximize the area Shift pointers according to whichever has a lower height. So if left has height of 1 and right has a height of 7, shift the left one to the right in the hopes of atatining a larger area. Keep track of max area as you do this

Word Search Given an m x n grid of characters board and a string word, return true if word exists in the grid. The word can be constructed from letters of sequentially adjacent cells, where adjacent cells are horizontally or vertically neighboring. The same letter cell may not be used more than once.

Find letter where word starts Then see if any neighboring characters that match the next one (without reusing characters already visited) Keep doing this Use set to keep track of path so you don't reuse anything i = current letter in word we're looking for return false if 1. finish entire word 2. out of bounds 3. see a character we're not looking for v4. isit the same position twice otherwise, add position to current path i.e. row, column to path and continue recursive dfs (run in all adjacent positions) res = (dfs(r + 1, c, i + 1)) or → leave column same and look for next char (dfs(r - 1, c, i + 1)) or → same but other direction for row (dfs(r, c + 1, i + 1)) → leave row same (dfs(r, c - 1, i + 1)) → leave row asme remove position just added to path because no longer need to visit that position since returning Run DFS on all of them and if any of them return true, return true (once word is found return true) then just run this DFS function on every position in the row (pass 0 for initial positon of i)

imortant notes group anagrams. (python stuff)

Important notes: defaultdict(list) makes default dictionary where the default value of each key is a list. Similarly defaultdict(int) makes default dictionary where the default value of each key is an int. This is useful when you want to work with keys without knowing if the value exists or not yet ord("a") → gives you the unicode code point of a character. Python doesn't allow you to have a list as a key for a dictionary, so if you want to do that convert the list into a tuple If you have an array where ach element is supposed to represent something for the letters, and you want it so that when you encounter a letter you update the corresponding index. you can use ord(c) - ord("a") as your way of indexing i think you could probably also do something where you map each letter to a value

Merge Intervals Given an array of intervals where intervals[i] = [starti, endi], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input. Example 1: Input: intervals = [[1,3],[2,6],[8,10],[15,18]] Output: [[1,6],[8,10],[15,18]] Explanation: Since intervals [1,3] and [2,6] overlap, merge them into [1,6].

First order the intervals according to start value (always do this with intervals) every time check if the current interval overlap with the previous interval and if it does merge the interval [note; draw a number line, it makes it a lot easier) Algorithmic complexity:O(n log n) where n is # intervals to sort: intervals.sort(key = lambda i : i[0]) bc 0 is start → important python lambda output set to first interval to avoid edge case go through each interval in sorted order through start, end (can skip the first interval since the first one is technically already in output) to see if overlapping, get the most recently added interval (output[-1]) and get the end value of it (output[-1][1]) = lastEnd check if the start <= lastEnd and if this is true, merge the intervals by taking the most recently added interval and changing the end value of it to the max of itself and the max of the current end value we're at in the case they're not overlapping add the interval to the output

Construct Binary Tree from Preorder and Inorder Traversal Given two integer arrays preorder and inorder where preorder is the preorder traversal of a binary tree and inorder is the inorder traversal of the same tree, construct and return the binary tree.

First value in each partition is root of subtree Identify root take length of left and right subarrays in inorder → counts tell us how to partition preorder traversal Recursive algorithm Base case If not preorder or not inorder → false Create root = Treenode from preorder[0]) mid = inorder.index(preorder[0]) Preorder Array: After the root element (at index 0), the next mid elements correspond to nodes of the left subtree, because the size of the left subtree is exactly mid (the number of elements before the root in the inorder array). Therefore, the boundary for the left subtree in the preorder array is from index 1 to mid (inclusive), which translates to preorder[1 : mid + 1]. Inorder Array: For the left subtree, we take all elements before mid in the inorder array. Hence, the boundary is inorder[:mid]. Here, we don't need to adjust the index because slicing up to mid excludes the midth element itself, which is the root. For the Right Subtree:

Invert Binary Tree Given the root of a binary tree, invert the tree, and return its root.

First, check to see if the root is null. If not, swap the root's children, and then recursively do the same for the root's left and right subtrees, and so on. Finally, return the root.

Meeting Rooms Given an array of meeting time intervals where intervals[i] = [starti, endi], determine if a person could attend all meetings. Example 1: Input: intervals = [[0,30],[5,10],[15,20]] Output: false

First, sort the intervals by start using lambda function [learn for python!!!] Then, iterate through, starting by 1 (so you can access the previous one), up to the length of the array Check if i2 starts before i1 ends and if so return false

Linked List Cycle Given head, the head of a linked list, determine if the linked list has a cycle in it. There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail's next pointer is connected to. Note that pos is not passed as a parameter. Return true if there is a cycle in the linked list. Otherwise, return false

Floyd's Tortoise and Hare Algorithm If you have fast pointer and slower pointer, they will eventually meet if a cycle exists

Maximum Product Subarray Given an integer array nums, find a subarray that has the largest product, and returnthe product. The test cases are generated so that the answer will fit in a 32-bit integer. Example 1: Input: nums = [2,3,-2,4] Output: 6 Explanation: [2,3] has the largest product 6.

Given an integer array nums, find a subarray that has the largest product, and return the product. The test cases are generated so that the answer will fit in a 32-bit integer. Brute force: try every subarray, find their respective products, then choose the max → O(n^2) If all elements are positive, just multiply everything because they'll increase no matter what If they're all negative numbers, the sign alternates so we need to keep tralk of the min prod subarray [-1, -2, -3] - max product subarray of first two elements AND minimum product subarray of first two elements - when include third element use those values; -3* 2 = -6 (minimum) and -3 * -2 = 6 (maximum) edge case: 0 - any time we get a 0, reset max and min to 1 (ignore it) so that when you introduce new values it'll be like 1 * 3 set result = to max(nums) just in case initially maintain the currentMin and currentMax and initialize them to 1 since it's natural value iterate through every number in array - if get 0 reset curMin and curMax to 1 and continue to next iteratio - before reassing curmax, set it in temp value - calculate curMax = max(n * curMax, n * curMin, n) - calculate curMin = min (tmp, n * curMin, n) -tmp since curmax was modified - res = max(res, curMax)

Merge Two Sorted Lists You are given the heads of two sorted linked lists list1 and list2. Merge the two lists into one sorted list. The list should be made by splicing together the nodes of the first two lists. Return the head of the merged linked list.

Have a dummy tail value and iterate through the two lists. On each iteration, set tail.next to whatever value is lower. Then update tail to the next node. After the loop, check if either list is empty. If they are empty, just add that entire thing to tail.next since it now can all be added since it's also sorted and the other list doesn't need to be taken into account Finally, return dummy.next in order to return the list

Longest Repeating Character Replacement You are given a string s and an integer k. You can choose any character of the string and change it to any other uppercase English character. You can perform this operation at most k times. Return the length of the longest substring containing the same letter you can get after performing the above operations.

Have a hashmap to take every character and count the number of occurences windowLen - count[most frequent character] = # of characters in our window right now we need to replace to make it match the most frequent character Confirm that windowLen - count[most frequent character] <= k because that means we have enough replacements to make those replacements in our current window If you exceed k (the # of replacements you'rea llowed to make), you need to shrink the size of the window until you're valid by shifting the left pointer to the right There's another way to do this without having to look through the entire hash map every time you want to find the most frequent character that occurs Keep a variable maxf to keep a count of the letter with the maximum frequency The result will only be maximized when we find a new max frequency length - maxf <= k [might want to change later]

NEETcode solution to TwoSum to look over

His solution is basically the same except he iterates using an enumerate() instead of having a separate i variable → enumerate keeps track of index and element. Also instead of doing the .get() he just gets the index through [ ] which I could also do, it's equivalent

Combination Sum Given an array of distinct integers candidates and a target integer target, return a list of all unique combinations of candidates where the chosen numbers sum to target. You may return the combinations in any order. The same number may be chosen from candidates an unlimited number of times. Two combinations are unique if the frequency of at least one of the chosen numbers is different. The test cases are generated such that the number of unique combinations that sum up to target is less than 150 combinations for the given input.

Initialization: res: An empty list that will eventually contain all the valid combinations that sum to target. Depth-First Search (DFS) Helper Function: The method defines a nested helper function dfs(i, cur, total) for the depth-first search:i: The current index in candidates being considered.cur: The current combination being built.total: The current sum of elements in cur. This function uses recursion to explore all possible combinations of the numbers in candidates that could sum up to target. Base Cases: If total equals target, the current combination cur is a valid combination, so a copy of it is appended to res (to avoid mutation issues), and the recursion returns. If i is out of bounds (greater than or equal to the length of candidates) or total exceeds target, the function returns immediately as no further valid combinations can be formed from this state. Recursive Calls: The function first tries including the current candidate (candidates[i]) in the combination:It appends candidates[i] to cur and makes a recursive call to dfs with the same i (since the same element can be reused), updating total to include candidates[i].After returning from the recursion, it pops the last element from cur to backtrack and explore other possibilities. Then, it makes a recursive call to dfs with i + 1 (to move to the next candidate) without adding the current candidate to cur, allowing the exploration of combinations without the current element. Initial Call to DFS: The DFS exploration starts with dfs(0, [], 0), indicating that the search starts from the first candidate with an empty combination and a total sum of 0. Return the Result: After the DFS search completes, res contains all unique combinations that sum to target, and the method returns res.

Maximum Subarray Given an integer array nums, find the subarray with the largest sum, and return its sum. Example 1: Input: nums = [-2,1,-3,4,-1,2,1,-5,4] Output: 6 Explanation: The subarray [4,-1,2,1] has the largest sum 6.

Keep incrementing right pointer but left pointer keeps getting shifted if we ever have a negative prefix Every time we have a negative prefix as we're getting the total sum, we remove it "Sliding Window" O(N) time complexity set maxSub to random value in array NOT 0 because there can be negative values in array and keep track of curSum then iterate through array and reset curSum every time you hit negatives

Validate Binary Search Tree Given the root of a binary tree, determine if it is a valid binary search tree (BST). A valid BST is defined as follows: The left subtree of a node contains only nodes with keys less than the node's key. The right subtree of a node contains only nodes with keys greater than the node's key. Both the left and right subtrees must also be binary search trees.

Key thing to keep in mind: make sure EVERY SINGLE value in right subtree is greater than root and vice versa for less; cant simply check neighbors O(N^2) would be brute force Idea: keep track of and update left and right boundary For root, it's -inf, +inf If you go left once, it's -inf < val < root → update left boundary If you go right once it's root < val < inf → update right boundary Time complexity: O(N)c

Subtree of Another Tree Given the roots of two binary trees root and subRoot, return true if there is a subtree of root with the same structure and node values of subRoot and false otherwise. A subtree of a binary tree tree is a tree that consists of a node in tree and all of this node's descendants. The tree tree could also be considered as a subtree of itself.

Logic of code: Helper function to determine if two trees are the same Main function has cases 1. If subtree is empty → true 2. If big tree is empty but subtree isn't → false 3.If the two trees rn are the same → true ^do this on every tree recursively by finding if either self.isSubtree(s.left, t) or self.isSubtree(s.right, t) is true (this will check for each subtree in the big tree if it is equal to the subtree)

Diameter of a Binary Tree Given the root of a binary tree, return the length of the diameter of the tree. The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root. The length of a path between two nodes is represented by the number of edges between them.

Longest path between any two nodes Find the max total path Start from the bottom and find the diameter of the bottom nodes first max variable = 0 For each of the nodes we want the diameter and height of the tree Find max(left, right) heihgt and add 1 to them because of the edge connecting the current node with others [note: consider the height of empty subtree -1) diameter + l + r + 2 (for each of these trees there'll be an edge; the -1 will cancel out)

Longest Substring Without Repeating Characters Given a string s, find the length of the longest substring without repeating characters.

Make sure our window/subarray does not contain any duplicates. Begin shrinking sliding window (popping from left) until we no longer have duplicates once you encounter duplicates To know if you have duplicate, use a set for substring since they only have one example of each character. Time complexity: O(n) → just have to go through the entire list Memory complexity: O(n) → because every character may be unique and we add all of them to the set For sliding window need left and right pointer Iterate through string using right pointer. In this loop, need to iterate to remove the leftmost character and update the left pointer if there are duplicates. Then add whatever's at right pointer to charSet

Top K Frequent Elements

O(N) TC make count hashmap make array to keep track of frequencies make hashmap to track count of numbers, then make freq list of lists where index is frequency and element is lists of that frequency, then iterate through freq in reverse order appending to result array and once result reaches length k return it Initialization: count: A dictionary that maps each unique number in nums to its frequency of occurrence. freq: A list of lists, where the index represents the frequency of any number, and each element is a list of numbers that have that frequency. The size of freq is len(nums) + 1 because the maximum frequency a number can have is len(nums) (if all elements are the same). Populating the count dictionary: The method iterates through each number n in nums, updating count so that each key (n) maps to the number of times n appears in nums. Organizing numbers by their frequency: Next, it iterates through the count dictionary, placing each number n into the freq list at the index corresponding to its frequency c. This step effectively groups numbers by their frequency. Selecting the top k frequent elements: The method then initializes an empty list res, intended to store the result. It iterates over the freq list in reverse order (starting from the highest possible frequency to the lowest non-zero frequency). This ensures that the most frequent elements are considered first. For each frequency level i, it iterates over the numbers in freq[i], adding them to res. This process is done because more frequent elements are more likely to be added to the result list early. Once the length of res reaches k, indicating that the top k frequent elements have been found, the method returns res.

Climbing Stairs You are climbing a staircase. It takes n steps to reach the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

O(N) bc each subproblem only solved once The result of 0 depends on subproblem on 1 which depends on another subproblem etc etc so on until it depends on the base case Solve the base case then work way up (bottom up) How many ways to reach 5 (first one is default vl) 5 → default 4 → 1 way 3 → 2 ways (1 step, 2 steps) 2 → it's going to be the way from 3 and 4, so 1 + 2 = 3 1 → it's going to be the way from 2 and 3, so 3 + 2 = 5 0 → 8

Valid Anagram Given two strings s and t, return true if t is an anagram of s, and false otherwise. An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.

O(S + T) for both time and memory complexity Solution 1: If your interviewer asks for a solution that uses no additional space, check if the two sorted strings are equal return sorted(s) == sorted(t) Solution 2: (borderline cheating) Python has a built in Counter thing that does this return Counter(s) == Counter(t) Solution 3: My solution just has 2 hash tables, one for s and one for t keeping track of the letter and its associated count, and at the end returns True if .items() is equal for both and false otherwise O(S + T) for both time and memory complexity

Non-overlapping intervals Given an array of intervals intervals where intervals[i] = [starti, endi], return the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping. Example 1: Input: intervals = [[1,2],[2,3],[3,4],[1,3]] Output: 1 Explanation: [1,3] can be removed and the rest of the intervals are non-overlapping.

O(n log n) bc sorting 1. sort the list of intervals 2. result to keep track of is count 3. initially keep track of first end value (intervals[0][1]) 4. iterate through remaining list of intervals start and end; start at index 1 bc already have first one in prevEnd - the intervals are not overlapping if the start value of current interval >= previous interval's end value (prevEnd). if not overlapping, just need to update prevEnd to new end value 5. if they are overlapping: - increment result count res += 1 - need to update prevEnd and set it to the minimum end value so min(end, prevEnd)

Reorder list You are given the head of a singly linked-list. The list can be represented as: L0 → L1 → ... → Ln - 1 → Ln Reorder the list to be on the following form: L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → ... You may not modify the values in the list's nodes. Only nodes themselves may be changed.

O(n) where n is size of linked list and O(1) memory 1. find middle point of list with slow and fast pointer, which will begin with slow.next after finding intersections 2. reverse second half of list 3. merge the two halves of the list note: slow.next = None is necessary to isolate the second half of the list, ensuring that only this portion is reversed.

Rotate Image You are given an n x n 2D matrix representing an image, rotate the image by 90 degrees (clockwise). You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation.

O(n^2) algorithmic time complexity, O(1) memory First, take care of the four corners; each one is being rotated to the next corner Same for the next 4..etc When you finish the outer square you can shift inwards to do the subproblem Once the pointers crossed each other you know there's no matrix left to rotate To avoid having to create a temporary variable every time you move numbers, do the rotations in reverse order. For example first move the one at the bottom left to the upper left, store the upper left variable somewhere, then do the bottom right Explaining the i stuff: We want to be able to on each iteration get closer in So the top left can move eright (hence the + i) The bottom left can move up (hence - i) The bottom right can move left (hence r - i) The top right can move down so + i

Reverse Linked List Given the head of a singly linked list, reverse the list, and return the reversed list. (iterative)

On each iteration, set the current nodes next pointer to the previous node, move up the previous node and the current node variable. At the end, return prev variable since curr node will be null due to while loop. O(1) Memory complexity O(N) Time complexity

Kth Smallest Element in a BST Given the root of a binary search tree, and an integer k, return the kth smallest value (1-indexed) of all the values of the nodes in the tre

Put every element in order and take the kth element (sorted array?) Go through every element in the left subtree before visiting current node. Once you reach null you know you went too far and can pop the latest element from stack (which you appended to stack before you start going all the way left) and increment n. Check if n == k, if so return cur.val. If not go into its right subtree

Best Time to Buy and Sell Stock You are given an array prices where prices[i] is the price of a given stock on the ith day. You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock. Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return 0.

Take the minimum and maximum price where there minimum's date must be before the maximum's date Use two pointers; left pointer on day 1 and right pointer on day 2 where left = buy and right = sell Check if left pointer is less than right pointer. Only shift left pointer forwards if it is greater than right pointer (since this implies the right pointer would be a better time to buy). O(1) Memory O(N) Time b/c 2 pointer solution → only need to scan through array 1x

Set Matrix Zeroes Given an m x n integer matrix matrix, if an element is 0, set its entire row and column to 0's. You must do it in place.

Solution #1: Have extra memory to keep track of which columns/rows you need to zero and THEN after iterating through the entire matrix make them 0; O(m*n) time complexity and O(m+n) space Make the standby array into the matrix Because the two extra arrays could overlap otherwise the one to represent columns will have 2 and the other will have 3 (1 extra memory to tell you if you have to 0 out last row or not) [ reason this works is we go top to bottom left to right so we don't overwrite anything]

Happy Number Write an algorithm to determine if a number n is happy. A happy number is a number defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits. Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy. Return true if n is a happy number, and false if not.

Starting with any positive integer, replace the number by the sum of the squares of its digits. Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy. Return true if n is a happy number, and false if not. Take first digit, square it, add second digit, square it, and add the sum 19 → 1^2 + 9^2 = 82 → 8^2 + 2^ = 68 Keep repeating this process If the number reaches a 1, then it's a happy number If it never does, it's not a happy number Either way it'll loop endlessly If a number is visited twice, you know it'll never find 1 and you can return false. The best way to keep track of this is a set so you can know in constant speed 19 % 10 → 9 (gets one place value) 19 // 10 = 1 → gets other value need to do this to make sum of squares helper

Decode Ways A message containing letters from A-Z can be encoded into numbers using the following mapping: 'A' -> "1" 'B' -> "2" ... 'Z' -> "26" To decode an encoded message, all the digits must be grouped then mapped back into letters using the reverse of the mapping above (there may be multiple ways). For example, "11106" can be mapped into: "AAJF" with the grouping (1 1 10 6) "KJF" with the grouping (11 10 6) Note that the grouping (1 11 06) is invalid because "06" cannot be mapped into 'F' since "6" is different from "06". Given a string s containing only digits, return the number of ways to decode it. The test cases are generated so that the answer fits in a 32-bit integer.

Subproblem: When you take 1 by itself and have the remainder, you're asking how many ways can you decode remaining of the string subproblem: some portion of the string to be able to solve the entire problem, need to solve the subproblem (how to decode everything except the beginning) dimension of cache (i counter): n → O(n) time complexity memory: O(n) → bc it's size of cache problem can be solved with O(1) memory because - dp[i] = dp[i + 1] + dp[i + 2] → don't need full array just need 2 variables #1 solution: O(n) memory using array cache ; recursive caching dp initialized with len(s) : 1 bc if get empty string want to return 1 in that case either already been cached or last position in string if not end of string, if it's not the end of the string need to check character. if character starts with 0 it's invalid so return 0 if not 0, it's between 1-9 so you know you can take as single digit so call dfs(i + 1) i.e. next character if there is as second character that comes after the other one in bounds, and the character starts with a 1 OR if it starts with a 2 and the digit is between 0 and 6

Maximum Depth of a Binary Tree Given the root of a binary tree, return its maximum depth. A binary tree's maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. BFS

The method enters a while loop that continues as long as q is not empty, indicating there are still nodes to visit. Inside the while loop, a for loop iterates over the current level's nodes (the current size of q represents all nodes at the current level). For each iteration, it pops a node from the left of the deque (node = q.popleft()). This is the BFS part of the traversal, where nodes are visited level by level. It then checks if the current node has left and/or right children. If so, these child nodes are appended to the q. This step ensures that all nodes on the next level will be visited in subsequent iterations. After iterating through all nodes at the current level, level is incremented by 1, indicating that the traversal has moved down one level in the tree. Return the Maximum Depth: Once the while loop exits (i.e., q is empty and there are no more nodes to visit), the traversal has reached the maximum depth of the tree. The method then returns level, which now contains the total number of levels in the tree, equivalent to the maximum depth.

Maximum Depth of a Binary Tree Given the root of a binary tree, return its maximum depth. A binary tree's maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. ITERATIVE DFS

The method enters a while loop, which continues as long as there are elements in the stack. In each iteration, it pops an element from the stack, which contains a node (node) and its depth (depth). If the current node is not None (to handle cases where the tree is empty or the node is a leaf), the method proceeds to update res with the maximum of its current value and the current depth. It then appends the left and right children of the current node to the stack, if they exist, along with their corresponding depths (which is depth + 1 since the children are one level deeper than the current node).

Product of Array Except Itself

This would be easy if you could use division operation because you could take the product all of these values and to find the value of any number you'd divide by that number To break this up, find the product of the values before the number, and the product of the values after the number, and the product of these two will be the number's value Compute the prefix product for every position in and in array and every postfix value in an array O(N) time complexity and memory First pass (left to right): The method iterates over the input list nums starting from the second element (index 1). For each index i, it sets res[i] to the product of all the elements to the left of nums[i]. This is achieved by multiplying res[i-1] (which already contains the product of elements to the left of nums[i-1]) with nums[i-1]. After this pass, each element in res contains the product of all elements to its left in nums. Second pass (right to left): The method then initializes a variable postfix with a value of 1. Starting from the last element of nums and moving backwards, it updates each element in res by multiplying it with postfix, which contains the product of all elements to the right of the current index in nums. After multiplying, it updates postfix by multiplying it with the current element in nums. This way, after this pass, res[i] contains the product of all elements to the left and right of nums[i], effectively excluding nums[i] itself. Return the result: Finally, the method returns the list res, which now contains the product of all elements except itself for each index in the original list.

3. Two Sum Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target. You may assume that each input would have exactly one solution, and you may not use the same element twice. You can return the answer in any order.

Time O(1) * n = O(N) Space O(N) My solution uses a hash table to keep track of the number → index but before adding that pair to the hash table it checks if the number needed to get the target (target - num) is already in the hash table and if so returns the answer. Otherwise, it adds the number + index into the hash table.

Longest Consecutive Sequence Given an unsorted array of integers nums, return the length of the longest consecutive elements sequence. You must write an algorithm that runs in O(n) time.

Time O(N) Space O(N) use set since sets only have unique elements iterate over every element in nums if previous number not in set --> reset count and make the current number this number while previous number in set --> increment result and increment currNum if currResult > result --> set resut equal to currResult finally return result [i dont think currNum is actually necessary]

Group Anagrams Given an array of strings strs, group the anagrams together. You can return the answer in any order.

Time complexity O(m * n) where m is total # of input strings and where n is the average length of a string because we have to count how many of every character there are Creating a character count array count: For each string s, it initializes a list count of length 26 (corresponding to the 26 letters of the English alphabet) with all elements set to 0. This list is used to count the frequency of each letter in the string. Populating the count array: For each character c in the string s, it calculates the difference between the ASCII value of c and the ASCII value of 'a' to find the index corresponding to c in the count array. It then increments the value at this index by 1. This way, the count array represents the frequency of each letter in s. Using count as a key in ans: Once the count array is populated for a string s, it converts count to a tuple (to make it hashable) and uses it as a key to append s to the corresponding list in ans. This means that all strings that result in the same count array (i.e., are anagrams of each other) are grouped together under the same key. Returning the groups of anagrams: Finally, the method returns the values of the ans dictionary. Since ans is a defaultdict with lists as values, ans.values() will be a collection of lists, where each list contains strings that are anagrams of each other.

Kth Largest Element In a Stream Design a class to find the kth largest element in a stream. Note that it is the kth largest element in the sorted order, not the kth distinct element. Implement KthLargest class: KthLargest(int k, int[] nums) Initializes the object with the integer k and the stream of integers nums. int add(int val) Appends the integer val to the stream and returns the element representing the kth largest element in the stream.

Use Min Heap Heap - Add/pop in log n - Get minimum in O(1) - Only need a minheap of size k because only need kth largest element 1. First take entire input and put into heap 2. While size of array > k pop the minimum from the array 3. Now once you have the resulting array just take the minimum of the values which will be 3rd largest if its 3 array Constructor function: n log n (pop function is log n and we may have to do it (n - k) times)) add function → add value to stream of data 1. Take value and add to minheap 2. Pop the minimum value 3. Return smallest value which will be kth largest O(m * log n) of add heapq.heapify(self.minHeap) → turns it into heap edge case: if array initially has less than k elements; only pop if length of heap is graeter than k minHeap

Sum of Two Integers Given two integers a and b, return the sum of the two integers without using the operators + and -.

Use XOR to compute the sum because if two one's → 0 two zero's → 0 1 and 0 → 1 which is the same as the results of adding bits to get the 1 carry in case of the two one's use (a & b) << 1 where you shift this to the left XOR operation and if you have a carry value add it again to whatever is elft remaining add together using the same operations (XOR first and then &<<1) so a is the XOR a would be the right answer unless theres a carry b checks if there is a carry and keeps updating to the carry when there is no carry anymore you're done each iteration (if there is more than one) does a XOR with the carried val and if that is the val and it has no furthe curry youre done which is why the loop works

Last Stone Weight You are given an array of integers stones where stones[i] is the weight of the ith stone. We are playing a game with the stones. On each turn, we choose the heaviest two stones and smash them together. Suppose the heaviest two stones have weights x and y with x <= y. The result of this smash is: If x == y, both stones are destroyed, and If x != y, the stone of weight x is destroyed, and the stone of weight y has new weight y - x. At the end of the game, there is at most one stone left. Return the weight of the last remaining stone. If there are no stones left, return 0.

Use maxheap because need the max stones in each iteration and replace the intact stone with new value (new value will be larger stone - smaller stone) TC: O(n log n) Python doesnt have maxheap so use a minheap to simulate maxheap by converting numbers to negatives and then converting it back into positive after popping - multiply all stone - values by -1 turn the list into heap by - heapq.heapify(stones) - while len(stones) >1, pop from heap.heappop(stones) - pop again for second largest (keep in mind second will have a larger value than first bc in negatives) - if second > first [actually means opposite] → heapq.heappush(stones, first - second) edge case: stones is empty stones.append(0) → adds something there in case there's nothing so itll return 0 in that return abs(stones[0]) to make it positive

Encode and Decode Strings Design an algorithm to encode a list of strings to a string. The encoded string is then sent over the network and is decoded back to the original list of strings. Machine 1 (sender) has the function: string encode(vector<string> strs) { // ... your code return encoded_string; } Machine 2 (receiver) has the function: vector<string> decode(string s) { //... your code return strs; } So Machine 1 does: string encoded_string = encode(strs); and Machine 2 does: vector<string> strs2 = decode(encoded_string); strs2 in Machine 2 should be the same as strs in Machine 1. Implement the encode and decode methods. You are not allowed to solve the problem using any serialize methods (such as eval).

Would be good to know how many characters in the first word, second word, etc so youd know encode the first 5 characters to first word, next x characters into secnd word, etc Could have an array → but you cant store any state variables per constraints Store ins tring itself like "4neet" BUT the problem is that the word could have an integer in it. Need another delmiiter. Have another delimiter inbtween such as 4# . Read each character until delimiter and after delimiter take all characters already read and then count the next 4 character after the delmiter 4#neet5#code time complexity: O(N) encode: res to store result in each iteration add to result the length of the string plus a pound sign plus the string itself decode: res to store result, i counter variable while iterating through string, have separate counter j (to locate #) while string inst equal to # increment j → this wil llet you know where pound is location then you know length = int(str[i:j]) bc it'll be the 1 character between i and j where j is nonexclusive then you know the beginning of the string is j + 1 and the total length is j + 1 + length so you can res.append(str[j + 1 : j + 1 + length]) you can set i = j + 1 + length to go to the next word since that's the length of the word

Reverse Bits Reverse bits of a given 32 bits unsigned integer. Note: Note that in some languages, such as Java, there is no unsigned integer type. In this case, both input and output will be given as a signed integer type. They should not affect your implementation, as the integer's internal binary representation is the same, whether it is signed or unsigned. In Java, the compiler represents the signed integers using 2's complement notation. Therefore, in Example 2 above, the input represents the signed integer -3 and the output represents the signed integer -1073741825.

bit = (n >> 1 ) & i → determines if bit is 1 or 0; isolates bit by shifting n by i res = res | (bit << (31 - i)) → changes bit in rseult starting backwards. OR converts whatever since if bit is 1 → become 1 if it's 0 stay 0. shift to the left 31 - i visualize the shifting bit → iterate through bits in integer by shifting to the right res → change the opposite bit by shifting left the opposite number from 32 number of times

Coin Change You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money. Return the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1. You may assume that you have an infinite number of each kind of coin.

calculate the minimum number of coins used for each amount up to the actual amount you want to calculate (this will allow you to generate teh amount for the one you actually want) the a - c >= 0 condition checks if this coin can be used to reach the amount or not; if it can, it checks whether there is already a more efficient way to reach that amount, or if not, adds using that coin + using [minimum # ways to get the remaining number needed for amount]

Meeting Rooms II Given an array of meeting time intervals intervals where intervals[i] = [starti, endi], return the minimum number of conference rooms required. Example 1: Input: intervals = [[0,30],[5,10],[15,20]] Output: 2

first sort the two arrays have variables for result, count, start pointer, end pointer while iterating through array (which s has to be less because itl be the one to finish first since start times are before ends times) if the start time is less than the end times at the index then increment s pointer and increment count (# meetings going on) if end time is more than start time than increment end pointer and decrement count this keeps going until s reaches end keep result while doing this

Plus One You are given a large integer represented as an integer array digits, where each digits[i] is the ith digit of the integer. The digits are ordered from most significant to least significant in left-to-right order. The large integer does not contain any leading 0's. Increment the large integer by one and return the resulting array of digits.

hard case: [9, 9, 9] + 1 how to get it to become 1000; need to keep track of carry TC: O(n) MC: O(1) carry is one i is index of position; else is reach end and stil have a 1 carry reverse digits array bc thats where youre addding (could also traveres in reverse order) will keep making 9 0 while it has a carry until it's able to simply increment and add one OR once it reaches end of list and theres nothing to do but to append it to the end

Valid Parentheses Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. An input string is valid if: Open brackets must be closed by the same type of brackets. Open brackets must be closed in the correct order. Every close bracket has a corresponding open bracket of the same type.

hashmap to map closed to open stack as an array iterate through each character in string if character is in map (i.e. it's closing) then check if stack has elements AND top element is the matching opening parentheses --> if so, pop, if not, return false if character opening append it to stack after everything runs return true if stack is empty and false otherwise

Longest Common Subsequence Given two strings text1 and text2, return the length of their longest common subsequence. If there is no common subsequence, return 0. A subsequence of a string is a new string generated from the original string with some characters (can be none) deleted without changing the relative order of the remaining characters. For example, "ace" is a subsequence of "abcde". A common subsequence of two strings is a subsequence that is common to both strings.

if you know the first characters equal each other (as in this case) then the subproblem becomes the longest common subsequence between [bcde] and [ce] + 1 (bc u already found one) if they weren't equal the subproblem would be between [bcde] and [ce] or [bbcde] and [ce] took the two input strings and broke them up in a 2d graph; when characters match go diagonally bc u know they match when first characters are not diagonally go right and down, look at the max of those two, and then put that in value\ default out of bounds value is 0 create 2d grid with list comprehension text2 + 1 bc need another column/row for the 0s 2d grid of dimensions len(tex2 + 1) and len(text1) + 1 set to 0s nested roop where we iterate through nested grid in reverse order; start at bottom right working way up if characters in both strings match: dp[i][j] = 1 + dp[i + 1][j + 1] which is 1 + diagonal if characters in both strings dont match: find max of value to the right and down so max(dp[i][j+1], dp[i+1][j]) return top left time and memory: O(n*m)

Search In Rotated Sorted Array There is an integer array nums sorted in ascending order (with distinct values). Prior to being passed to your function, nums is possibly rotated at an unknown pivot index k (1 <= k < nums.length) such that the resulting array is [nums[k], nums[k+1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]] (0-indexed). For example, [0,1,2,4,5,6,7] might be rotated at pivot index 3 and become [4,5,6,7,0,1,2]. Given the array nums after the possible rotation and an integer target, return the index of target if it is in nums, or -1 if it is not in nums. You must write an algorithm with O(log n) runtime complexity.

log n → binary search Determine left vs right orted portion IF middle value is >= left → middle value is in left sorted portion * if target is less than leftmost value, search right * run normal binary search first initialize pointers 0 and length of array make sure l and r are <= to each other because if array has 1 value have to check l = mid + 1 → go right r = mid - 1 → go left when you're in the left sorted portion, you search left if the target is greater than mid (since mid is the largest value in the left sorted portion) the target is les than the leftmost value when you're in the left sorted portion, you search right if neither of these are true (i.e. the target is less than the middle but not less than the leftmost value which means it must be to the left) when you're in the right sorted portion you search left if: the target is less than the middle value (since mid is the smallest value in the right sorted portion) the target is greater than the rightmost value (since thats the max value in the right portiona0 when you're in the right sorted portion you search right if: neither of these are true (i.e. the target is more than the middle but not more than the rightmost value which means it must be in the right portion)

Clone Graph Given a reference of a node in a connected undirected graph. Return a deep copy (clone) of the graph. Each node in the graph contains a value (int) and a list (List[Node]) of its neighbors. class Node { public int val; public List<Node> neighbors; }

oldToNew: A dictionary that maps nodes from the original graph (old) to their corresponding nodes in the cloned graph (new). Depth-First Search (DFS) Helper Function: The method includes a nested helper function dfs(node) which is used to traverse the graph starting from the given node and clone it recursively. For each node encountered during the traversal, the DFS function performs the following steps: Check if Node is Already Cloned: If the current node is already present in the oldToNew dictionary, it means the node has already been cloned. The function then immediately returns the cloned node to avoid duplication and infinite recursion in case of cycles. Clone the Current Node: If the node is not yet cloned, a new node instance (copy) is created with the same value as the original node. This new node is then added to the oldToNew dictionary, mapping the original node to the newly created clone. Clone Neighbors: The function iterates through the neighbors of the current node. For each neighbor, it recursively calls dfs(nei) to clone the neighbor (if not already cloned) and then appends the cloned neighbor to the copy node's neighbors. This step ensures that all the connections (edges) are preserved in the cloned graph. Return the Cloned Node: After cloning the node and its neighbors, the cloned node (copy) is returned. Cloning the Graph: The method starts the cloning process by calling dfs(node) with the given node as the starting point. This recursive DFS traversal ensures that every node reachable from the starting node is cloned along with its edges. If the input node is None (indicating an empty graph), the method returns None to indicate that there is no graph to clone. Return Statement: The method returns the result of the dfs(node) call if the node is not None; otherwise, it returns None.

House Robber You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security systems connected and it will automatically contact the police if two adjacent houses were broken into on the same night. Given an integer array nums representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police.

only need to maintain the last two maxes maintain the maximum you can rob up until now (rob2 is last house robbed and rob1 was the voice before that - >there's a gap between the current house and previous house)

alternate valid palindrome solution with using your own alpha numeric function

option 2: use pointers from the left and right and keep checking if they're equal the way to avoid using alphanumeric functions is using ascii values eventually the strings will meet at the middle, after which we've determined we're at the solution O(N) → algorithm O(1) → no space used helper function alphanum to use ascii values to check if something is ascii values are contiguous → use these to find the ones between A and Z, a and z, 0 and 9 ord function

Binary Search Given an array of integers nums which is sorted in ascending order, and an integer target, write a function to search target in nums. If target exists, then return its index. Otherwise, return -1. You must write an algorithm with O(log n) runtime complexity.

sorted array Two pointers: one at leftmost index (initially 0), one at rightmost index Middle = Left + Right / 2 (integer division) If middle is not target, ask if it's smaller or larger than the target If smaller than target: have to look right (since everything before middle will be even smaller) by shifting left pointer to m + 1 If larger than target, have to look left by shifting right pointer to m - 1 Recalculate middle Continue until you find the number O(log n) bc keeps going for as many times as you can divide by 2 in worst case (base 2) l <= r we have no more values left to search; stop if left pointer has crosse dright pointer

Word Break Given a string s and a dictionary of strings wordDict, return true if s can be segmented into a space-separated sequence of one or more dictionary words. Note that the same word in the dictionary may be reused multiple times in the segmentation. Example 1: Input: s = "leetcode", wordDict = ["leet","code"] Output: true Explanation: Return true because "leetcode" can be segmented as "leet code"

starting at last index and working way to beginning for each position i, try every word in worddic and see if the word matches portion - check if starting at position i, the string s has enough characters for w to be compared to AND if the characters from the index up to the length of the words are the same as the word then dp[i] = dp[i + len(w)]

Valid Palindrome A phrase is a palindrome if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers. Given a string s, return true if it is a palindrome, or false otherwise.

store empty string variable for every character in string, if character is alphanumeric, add the lowercase version of the character to the variable then check if that is the same forwards and backwards using newStr = newStr[::-1]

Missing Number Given an array nums containing n distinct numbers in the range [0, n], return the only number in the range that is missing from the array. Constraints: O(1) space and O(N) runtime

taking two numbers that are the same XOR is going to get you 0; when you XOR something with 0 you get the original number; To find the missing number,if you have range [0, 3] i.e. [0, 1, 2, 3] XOR it with input array [0, 1, 3] since everything will cancel out except the number you want O(2n) bc iterating through two arrays Additional solution: Take sum of the range [0,3] and subtract the sum of the input array. The result will be the missing number. Taking these sums would be O(N) each and memory complexity is O(1) → easiest solution

Insert Interval You are given an array of non-overlapping intervals intervals where intervals[i] = [starti, endi] represent the start and the end of the ith interval and intervals is sorted in ascending order by starti. You are also given an interval newInterval = [start, end] that represents the start and end of another interval. Insert newInterval into intervals such that intervals is still sorted in ascending order by starti and intervals still does not have any overlapping intervals (merge overlapping intervals if necessary). Return intervals after the insertion. Example 1: Input: intervals = [[1,3],[6,9]], newInterval = [2,5] Output: [[1,5],[6,9]]

time complexity O(n) iterate through every interval in the input case 1: check if new interval end value is less than start value of interval currently at → take new interval and insert it into the result (any other interval will be non-overlapping). can now return res + intervals[i:] i.e. interval fro current interval onwards with new interval added case 2: interval goes after current interval (start value of new interval is greater than the end value of current interval) append after current interval case 3: interval is overlapping with currenti interval. merge the current interval with interval we're at by taking the minimum of the start value of both intervals and the maximum value of the end values (after this cases we cant just add it immediately bc newInterval could still be overlapping) after the entire loop is done, append the interval into the result finally return

Longest increasing subsequence Given an integer array nums, return the length of the longest strictly increasing subsequence . Example 1: Input: nums = [10,9,2,5,3,7,101,18] Output: 4 Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4. subsequence is an array that can be derived from another array by deleting some or no elements without changing the order of the remaining elements

to calculate each longest increasing sequence - - for the last number it's going to be 1 bc nowhere else they can go - for all other numbers it's going to be max of 1 (just taking current num) and 1 + the LIS of every number ahead of it, BUT you can only take the LIS of numbers ahead of it if the number ahead is more than the current number to maintain the increasing order

Number of 1 Bits Write a function that takes the binary representation of an unsigned integer and returns the number of '1' bits it has (also known as the Hamming weight).

to know if a bit is a 1 - can AND with 1 → if it's 1 you know it's a 1 - can mod (%) by 2 → if it's 1 you know it's a 1, if it's a 0 you know it's a 0 to be able to look at the first bit every time, shift all of the bits to the right by 1 (each iteration) once we have 0's after shifting to right know you're done time complexity: 32-bit integer so O(32) aka O(1). no memory complexity drawback is it has to look at every bit even the ones that aren't 1; it'd be ideal if it only had to run for as long as there are 1's

Min Cost Climbing Stairs You are given an integer array cost where cost[i] is the cost of ith step on a staircase. Once you pay the cost, you can either climb one or two steps. You can either start from the step with index 0, or the step with index 1. Return the minimum cost to reach the top of the floor.

top floor is position after last index in array solve problem right to left take the minimum of 1 jump or 2 jump to get to final and put that as value in array so that every space in array represents total cost from there to the end goal return the minimum of the first two values since those are the only ones you can start from TC: O(n) MC: O(1) → using input array itself or two variables append 0 to it to make math easier iterate through array in reverse order; we should start at second to last value since the last value to get to the result is jut itself which is gonna be - 3 since we added an extra spot

Remove Nth Node From End off List Given the head of a linked list, remove the nth node from the end of the list and return its head. Input: head = [1,2,3,4,5], n = 2 Output: [1,2,3,5]

two pointers: left pointer and right pointer shifted by n keep shifting right pointer by 1, keep shifting left pointer by 1 when right pointer is at null, left pointer will be exactly at the node you want to delete because the offset between them is n to delete it, take the pointer of the previous node and reassign it to the node after the deleted one. but this is a probelem since you're currently at the node you want to delete but you want to access the link of the node before it. so solve this using a dummy node inserted at the beginning of the list. left pointer will be initialized at this dummy node now so that when right pointer reaches null we're at the node we want to return the new linked list, simply do dummy.next O(N) because two pointer technique


Kaugnay na mga set ng pag-aaral

Missouri Compromise, Compromise of 1850 and The Fugitive Slave Law

View Set

Fundamentals of Nursing - Physiological Aspects of Care

View Set