Own Daily Challenge Flashcards

1
Q

Sort Integers by The Number of 1 Bits

You are given an integer array arr. Sort the integers in the array in ascending order by the number of 1’s in their binary representation and in case of two or more integers have the same number of 1’s you have to sort them in ascending order.

Return the array after sorting it.

Input: arr = [0,1,2,3,4,5,6,7,8]
Output: [0,1,2,4,8,3,5,6,7]
Explantion: [0] is the only integer with 0 bits.
[1,2,4,8] all have 1 bit.
[3,5,6] have 2 bits.
[7] has 3 bits.
The sorted array by bits is [0,1,2,4,8,3,5,6,7]

A
class Solution:
    def sortByBits(self, arr: List[int]) -> List[int]:
        def customSortKey(num):
            count = bin(num).count("1")
            return (count, num)
        arr.sort(key = customSortKey)
        return arr
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Lowest Common Ancestor of a Binary Tree
Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

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).”
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.

A
# Definition for a binary tree node.
# class TreeNode:
#     def \_\_init\_\_(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if not root:
            return None
        
        if root == p or root == q:
            return root
        
        #Potential ancestor anchors
        leftNode = self.lowestCommonAncestor(root.left, p, q)
        rightNode = self.lowestCommonAncestor(root.right, p, q)

        if leftNode and rightNode:
            return root
        
        #Both on same side. Whatever one we found first (the one that fired the root == p or root = q condition first) is the ancestor
        if leftNode:
            return leftNode
        
        if rightNode:
            return rightNode
        #O(n) #NOT O(H) because that is for BST. You can make determination of going left vs right. In binary tree case, need to go everywhere.
        #O(h)
        
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Maximum Product of Two Elements in an Array
Given the array of integers nums, you will choose two different indices i and j of that array. Return the maximum value of (nums[i]-1)(nums[j]-1).
Input: nums = [3,4,5,2]
Output: 12
Explanation: If you choose the indices i=1 and j=2 (indexed from 0), you will get the maximum value, that is, (nums[1]-1)
(nums[2]-1) = (4-1)(5-1) = 34 = 12.

A
class Solution:
    def maxProduct(self, nums: List[int]) -> int:
        #Track two biggest values
        biggest, secondBiggest = 0, 0

        for n in nums:
            if n > biggest:
                secondBiggest = biggest
                biggest = n
            else:
                #If not greater than biggest, at least it can be second biggest still.
                secondBiggest = max(secondBiggest, n)
        return (biggest - 1) * (secondBiggest - 1)
        #O(n)
        #O(1)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Maximum Difference Between Node and Ancestor
Given the root of a binary tree, find the maximum value v for which there exist different nodes a and b where v = |a.val - b.val| and a is an ancestor of b.

A node a is an ancestor of b if either: any child of a is equal to b or any child of a is an ancestor of b.

Input: root = [8,3,10,1,6,null,14,null,null,4,7,13]
Output: 7
Explanation: We have various ancestor-node differences, some of which are given below :
|8 - 3| = 5
|3 - 7| = 4
|8 - 1| = 7
|10 - 13| = 3
Among all possible differences, the maximum value of 7 is obtained by |8 - 1| = 7.

A
# Definition for a binary tree node.
# class TreeNode:
#     def \_\_init\_\_(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def maxAncestorDiff(self, root: Optional[TreeNode]) -> int:
        res = 0
        def dfs(root, curMin, curMax):
            nonlocal res
            if not root:
                return 
            #The idea is that we want to compare the current root node (child) to a previous ancestor.
            #We check both combinations.. smallest ancestor - root.val, biggest ancestor - root.val
            #On first execution, res is 0 since root.
            #On subsequent iterations, minAncestor and maxAncestor will change as we move on to subsequent children deeper.
            res = max(res, abs(curMax - root.val), abs(curMin - root.val))
            dfs(root.left, min(curMin, root.val), max(curMax, root.val))
            dfs(root.right, min(curMin, root.val), max(curMax, root.val))
        dfs(root, root.val, root.val)
        return res
        #O(n)
        #O(h)
        
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Leaf-Similar Trees

Consider all the leaves of a binary tree, from left to right order, the values of those leaves form a leaf value sequence.

For example, in the given tree above, the leaf value sequence is (6, 7, 4, 9, 8).

Two binary trees are considered leaf-similar if their leaf value sequence is the same.

Return true if and only if the two given trees with head nodes root1 and root2 are leaf-similar.

A
# Definition for a binary tree node.
# class TreeNode:
#     def \_\_init\_\_(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def leafSimilar(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> bool:
        def dfs(root, res):
            if not root:
                return
            if not root.left and not root.right:
                res.append(root.val)
                return
            dfs(root.left, res)
            dfs(root.right, res)
        res1 = []
        res2 = []
        dfs(root1, res1)
        dfs(root2, res2)
        return res1 == res2
        #O(n)
        #O(n)
        
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Determine if String Halves Are Alike

You are given a string s of even length. Split this string into two halves of equal lengths, and let a be the first half and b be the second half.

Two strings are alike if they have the same number of vowels (‘a’, ‘e’, ‘i’, ‘o’, ‘u’, ‘A’, ‘E’, ‘I’, ‘O’, ‘U’). Notice that s contains uppercase and lowercase letters.

Return true if a and b are alike. Otherwise, return false.

Input: s = “textbook”
Output: false
Explanation: a = “text” and b = “book”. a has 1 vowel whereas b has 2. Therefore, they are not alike.
Notice that the vowel o is counted twice.

A
class Solution:
    def halvesAreAlike(self, s: str) -> bool:
        vowels = set(["a", "e", "i", "o", "u", "A", "E", "I", "O", "U"])
        i, j = 0, len(s) // 2

        s1Count, s2Count = 0, 0
        #Even length!
        while j < len(s):
            c1, c2 = s[i], s[j]
            if c1 in vowels:
                s1Count += 1
            if c2 in vowels:
                s2Count += 1
            i += 1
            j += 1
        return s1Count == s2Count
        #O(n)
        #O(1) #for vowels. 2 pointers avoids the string creations
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Unique Number of Occurrences

Given an array of integers arr, return true if the number of occurrences of each value in the array is unique or false otherwise.

Input: arr = [1,2,2,1,1,3]
Output: true
Explanation: The value 1 has 3 occurrences, 2 has 2 and 3 has 1. No two values have the same number of occurrences.

A
class Solution:
    def uniqueOccurrences(self, arr: List[int]) -> bool:
        counts = Counter(arr)
        return len(set(counts.values())) == len(counts.keys())
        #O(n)
        #O(n)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Set Mismatch

You have a set of integers s, which originally contains all the numbers from 1 to n. Unfortunately, due to some error, one of the numbers in s got duplicated to another number in the set, which results in repetition of one number and loss of another number.

You are given an integer array nums representing the data status of this set after the error.

Find the number that occurs twice and the number that is missing and return them in the form of an array.

Input: nums = [1,2,2,4]
Output: [2,3]

A

class Solution:
def findErrorNums(self, nums: List[int]) -> List[int]:
counts = Counter(nums)

    missing, dupe = -1, -1
    n = len(nums)

    for i in range(1, n + 1):
        if i not in counts:
            missing = i
        elif counts[i] == 2:
            dupe = i
    return [dupe, missing]
    #O(n)
    #O(n)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Maximum Length of a Concatenated String with Unique Characters
You are given an array of strings arr. A string s is formed by the concatenation of a subsequence of arr that has unique characters.

Return the maximum possible length of s.

A 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.
Input: arr = [“un”,”iq”,”ue”]
Output: 4
Explanation: All the valid concatenations are:
- “”
- “un”
- “iq”
- “ue”
- “uniq” (“un” + “iq”)
- “ique” (“iq” + “ue”)
Maximum length is 4.
Example 2:

A
class Solution:
    def maxLength(self, arr: List[str]) -> int:
        charSet = set()
        res = 0
        def overlap(charSet, s):
            prev = set()
            for c in s:
                if c in charSet or c in prev:
                    return True
                prev.add(c)
            return False
        def dfs(i):
            nonlocal res
            if i == len(arr):
                res = max(res, len(charSet))
                return
            #include i
            if not overlap(charSet, arr[i]):
                curS = arr[i]
                for c in curS:
                    charSet.add(c)
                
                dfs(i + 1)

                for c in curS:
                    charSet.remove(c)
            #Don't include i
            dfs(i + 1)
        dfs(0)
        return res
        #O(2 ^ n * m) #number of words, m avg length of word.
        #O(nm) #number of words is the height. each avg length of m added to charSet.
        

        
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Implement Queue using Stacks

Implement a first in first out (FIFO) queue using only two stacks. The implemented queue should support all the functions of a normal queue (push, peek, pop, and empty).

Implement the MyQueue class:

void push(int x) Pushes element x to the back of the queue.
int pop() Removes the element from the front of the queue and returns it.
int peek() Returns the element at the front of the queue.
boolean empty() Returns true if the queue is empty, false otherwise.
Notes:

You must use only standard operations of a stack, which means only push to top, peek/pop from top, size, and is empty operations are valid.
Depending on your language, the stack may not be supported natively. You may simulate a stack using a list or deque (double-ended queue) as long as you use only a stack’s standard operations.

Input
[“MyQueue”, “push”, “push”, “peek”, “pop”, “empty”]
[[], [1], [2], [], [], []]
Output
[null, null, null, 1, 1, false]

Explanation
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false

A
class MyQueue:

    def \_\_init\_\_(self):
        self.s1 = []
        self.s2 = [] #represents the actual queue basically

    def push(self, x: int) -> None:
        self.s1.append(x)

    def pop(self) -> int:
        if not self.s2:
            while self.s1:
                self.s2.append(self.s1.pop())
        return self.s2.pop()

    def peek(self) -> int:
        if not self.s2:
            while self.s1:
                self.s2.append(self.s1.pop())
        return self.s2[-1]

    def empty(self) -> bool:
        return not self.s1 and not self.s2
    #O(1) per operation basically. If have to take O(N) operation due to s2 empty, then we do that. But since there are N elements an 2N operations (each elt pushed popped once), amortized O(1) per op
    #O(n) space for two stacks

Your MyQueue object will be instantiated and called as such:
# obj = MyQueue()
# obj.push(x)
# param_2 = obj.pop()
# param_3 = obj.peek()
# param_4 = obj.empty()
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Flood Fill

An image is represented by an m x n integer grid image where image[i][j] represents the pixel value of the image.

You are also given three integers sr, sc, and color. You should perform a flood fill on the image starting from the pixel image[sr][sc].

To perform a flood fill, consider the starting pixel, plus any pixels connected 4-directionally to the starting pixel of the same color as the starting pixel, plus any pixels connected 4-directionally to those pixels (also with the same color), and so on. Replace the color of all of the aforementioned pixels with color.

Return the modified image after performing the flood fill.

Input: image = [[1,1,1],[1,1,0],[1,0,1]], sr = 1, sc = 1, color = 2
Output: [[2,2,2],[2,2,0],[2,0,1]]
Explanation: From the center of the image with position (sr, sc) = (1, 1) (i.e., the red pixel), all pixels connected by a path of the same color as the starting pixel (i.e., the blue pixels) are colored with the new color.
Note the bottom corner is not colored 2, because it is not 4-directionally connected to the starting pixel.

A
class Solution:
    def floodFill(self, image: List[List[int]], sr: int, sc: int, color: int) -> List[List[int]]:
        ROWS, COLS = len(image), len(image[0])
        visit = set()
        directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]
        startingColor = image[sr][sc]
        def dfs(r, c):
            if r < 0 or r == ROWS or c < 0 or c == COLS or image[r][c] != startingColor or (r, c) in visit:
                return
            visit.add((r, c))
            image[r][c] = color
            for dr, dc in directions:
                neiR, neiC = r + dr, c + dc
                dfs(neiR, neiC)
        dfs(sr, sc)
        return image
        #O(mn)
        #O(mn)

        
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Divide Array Into Arrays With Max Difference

You are given an integer array nums of size n and a positive integer k.

Divide the array into one or more arrays of size 3 satisfying the following conditions:

Each element of nums should be in exactly one array.
The difference between any two elements in one array is less than or equal to k.
Return a 2D array containing all the arrays. If it is impossible to satisfy the conditions, return an empty array. And if there are multiple answers, return any of them.

Input: nums = [1,3,4,8,7,9,3,5,1], k = 2
Output: [[1,1,3],[3,4,5],[7,8,9]]
Explanation: We can divide the array into the following arrays: [1,1,3], [3,4,5] and [7,8,9].
The difference between any two elements in each array is less than or equal to 2.
Note that the order of elements is not important.

A
class Solution:
    def divideArray(self, nums: List[int], k: int) -> List[List[int]]:
        nums.sort()
        res = []
        for i in range(0, len(nums), 3):
            if nums[i + 2] - nums[i] <= k:
                res.append(nums[i: i + 3])
            else:
                return []
        return res
        #O(n log n)
        #O(n) for res
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Count Nodes Equal to Average of Subtree

Given the root of a binary tree, return the number of nodes where the value of the node is equal to the average of the values in its subtree.

Note:

The average of n elements is the sum of the n elements divided by n and rounded down to the nearest integer.
A subtree of root is a tree consisting of root and all of its descendants.

Input: root = [4,8,5,0,1,null,6]
Output: 5
Explanation:
For the node with value 4: The average of its subtree is (4 + 8 + 5 + 0 + 1 + 6) / 6 = 24 / 6 = 4.
For the node with value 5: The average of its subtree is (5 + 6) / 2 = 11 / 2 = 5.
For the node with value 0: The average of its subtree is 0 / 1 = 0.
For the node with value 1: The average of its subtree is 1 / 1 = 1.
For the node with value 6: The average of its subtree is 6 / 1 = 6.

A
# Definition for a binary tree node.
# class TreeNode:
#     def \_\_init\_\_(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def averageOfSubtree(self, root: TreeNode) -> int:
        res = 0

        #returns the sum, and num nodes in subtree
        def dfs(root):
            nonlocal res
            if not root:
                return 0, 0
            #if leaf
            if not root.left and not root.right:
                res += 1
                return root.val, 1
            
            leftSum, leftCount = dfs(root.left)
            rightSum, rightCount = dfs(root.right)
            
            totalCount = leftCount + rightCount + 1
            totalSum = leftSum + rightSum + root.val
            avg = totalSum // totalCount
            if avg == root.val:
                res += 1
            return totalSum, totalCount
        dfs(root)
        return res
        #O(n)
        #O(h)
            
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Max Consecutive Ones
Given a binary array nums, return the maximum number of consecutive 1’s in the array.

Input: nums = [1,1,0,1,1,1]
Output: 3
Explanation: The first two digits or the last three digits are consecutive 1s. The maximum number of consecutive 1s is 3.

A
class Solution:
    def findMaxConsecutiveOnes(self, nums: List[int]) -> int:
        l = 0
        res = 0
        for r in range(len(nums)):
            if nums[r] == 0:
                l = r + 1
            else:
                res = max(res, r - l + 1)
        return res
        #O(n)
        #O(1)
                
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Sort Characters By Frequency

Given a string s, sort it in decreasing order based on the frequency of the characters. The frequency of a character is the number of times it appears in the string.

Return the sorted string. If there are multiple answers, return any of them.

Example 1:

Input: s = “tree”
Output: “eert”
Explanation: ‘e’ appears twice while ‘r’ and ‘t’ both appear once.
So ‘e’ must appear before both ‘r’ and ‘t’. Therefore “eetr” is also a valid answer.
Example 2:

Input: s = “cccaaa”
Output: “aaaccc”
Explanation: Both ‘c’ and ‘a’ appear three times, so both “cccaaa” and “aaaccc” are valid answers.
Note that “cacaca” is incorrect, as the same characters must be together.
Example 3:

Input: s = “Aabb”
Output: “bbAa”
Explanation: “bbaA” is also a valid answer, but “Aabb” is incorrect.
Note that ‘A’ and ‘a’ are treated as two different characters.

A
class Solution:
    def frequencySort(self, s: str) -> str:
        # counts = Counter(s)
        # maxHeap = [(-count, c) for c, count in counts.items()]
        # heapq.heapify(maxHeap)
        # res = []
        # while maxHeap:
        #     count, c = heapq.heappop(maxHeap)
        #     res.append(c * -count)
        # return "".join(res)
        #O(n) + 26 log 26 for the heap
        #O(n) for counter, then O(26) for heap

        counts = Counter(s)
        # freqs = [[] for i in range(len(s) + 1)]
        buckets = defaultdict(list)
        for c, count in counts.items():
            buckets[count].append(c)
        res = []
        for i in range(len(s), -1, -1):
            for c in buckets[i]:
                res.append(i * c)
        return "".join(res)
        # #Bucket sort solution
        # #O(n) for counter, then O(n) for actually finding and sorting decreasingly.
        # #O(n) for the array. worst cases can be [[.........], [], [], []]
        #Pretty much the same thing as the freqs thing you usually do.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Power of Two

Given an integer n, return true if it is a power of two. Otherwise, return false.

An integer n is a power of two, if there exists an integer x such that n == 2x.

Input: n = 1
Output: true
Explanation: 20 = 1

A
class Solution:
    def isPowerOfTwo(self, n: int) -> bool:
        if n <= 0:
            return False
        power = log2(n)
        if (power != int(power)):
            return False
        return True
        #O(1) #math to just take the log
        #O(1)
17
Q

Find the Town Judge
In a town, there are n people labeled from 1 to n. There is a rumor that one of these people is secretly the town judge.

If the town judge exists, then:

The town judge trusts nobody.
Everybody (except for the town judge) trusts the town judge.
There is exactly one person that satisfies properties 1 and 2.
You are given an array trust where trust[i] = [ai, bi] representing that the person labeled ai trusts the person labeled bi. If a trust relationship does not exist in trust array, then such a trust relationship does not exist.

Return the label of the town judge if the town judge exists and can be identified, or return -1 otherwise.

Input: n = 3, trust = [[1,3],[2,3]]
Output: 3

A
class Solution:
    def findJudge(self, n: int, trust: List[List[int]]) -> int:
        inDegree = defaultdict(int)
        outDegree = defaultdict(int)
        for a, b in trust:
            inDegree[b] += 1
            outDegree[a] += 1
        for candidate in range(1, n + 1):
            if outDegree[candidate] == 0 and inDegree[candidate] == n - 1:
                return candidate
        return -1
        #O(m + n) for trust array iteration and n int
        #O(n) as degrees go from 1 to n.
18
Q

Even Odd Tree

A binary tree is named Even-Odd if it meets the following conditions:

The root of the binary tree is at level index 0, its children are at level index 1, their children are at level index 2, etc.
For every even-indexed level, all nodes at the level have odd integer values in strictly increasing order (from left to right).
For every odd-indexed level, all nodes at the level have even integer values in strictly decreasing order (from left to right).
Given the root of a binary tree, return true if the binary tree is Even-Odd, otherwise return false.

Input: root = [1,10,4,3,null,7,9,12,8,6,null,null,2]
Output: true
Explanation: The node values on each level are:
Level 0: [1]
Level 1: [10,4]
Level 2: [3,7,9]
Level 3: [12,8,6,2]
Since levels 0 and 2 are all odd and increasing and levels 1 and 3 are all even and decreasing, the tree is Even-Odd.

A

Definition for a binary tree node.

# Definition for a binary tree node.
# class TreeNode:
#     def \_\_init\_\_(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isEvenOddTree(self, root: Optional[TreeNode]) -> bool:
        q = deque([root])
        even = True

        while q:
            prev = -float('inf') if even else float('inf')
            for _ in range(len(q)):
                cur = q.popleft()
                if even and not (cur.val % 2 and cur.val > prev):
                    return False
                elif not even and not (cur.val % 2 == 0 and cur.val < prev):
                    return False
                prev = cur.val
                if cur.left:
                    q.append(cur.left)
                if cur.right:
                    q.append(cur.right)
            even = not even
        return True
        #O(n)
        #O(n)
19
Q

Remove Zero Sum Consecutive Nodes from Linked List

Given the head of a linked list, we repeatedly delete consecutive sequences of nodes that sum to 0 until there are no such sequences.

After doing so, return the head of the final linked list. You may return any such answer.

(Note that in the examples below, all sequences are serializations of ListNode objects.)

Input: head = [1,2,-3,3,1]
Output: [3,1]
Note: The answer [1,2,1] would also be accepted.
Example 2:

Input: head = [1,2,3,-3,4]
Output: [1,2,4]
Example 3:

Input: head = [1,2,3,-3,-2]
Output: [1]

A
# Definition for singly-linked list.
# class ListNode:
#     def \_\_init\_\_(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeZeroSumSublists(self, head: Optional[ListNode]) -> Optional[ListNode]:
        dummy = ListNode(0, head)
        cur = dummy
        prefixSum = 0
        prefixSumToNode = {0: dummy}

        #Calculate prefix sums mapped to each node. Overwrite same prefix sum with the one after
        #for longer sequence
        while cur:
            prefixSum += cur.val
            prefixSumToNode[prefixSum] = cur
            cur = cur.next
        prefixSum = 0
        cur = dummy
        while cur:
            prefixSum += cur.val #0 for dummy, otherwise is the val
            #We find the node that has a prefix sum of prefixSum, and then
            #we delete that consecutive sequence by pointing cur to the node after that
            prefixSumNode = prefixSumToNode[prefixSum]
            cur.next = prefixSumNode.next
            cur = cur.next
        return dummy.next
        #O(n) for linked list
        #O(n) for hashmap
20
Q

Find the Pivot Integer
Given a positive integer n, find the pivot integer x such that:

The sum of all elements between 1 and x inclusively equals the sum of all elements between x and n inclusively.
Return the pivot integer x. If no such integer exists, return -1. It is guaranteed that there will be at most one pivot index for the given input.

Example 1:

Input: n = 8
Output: 6
Explanation: 6 is the pivot integer since: 1 + 2 + 3 + 4 + 5 + 6 = 6 + 7 + 8 = 21.
Example 2:

Input: n = 1
Output: 1
Explanation: 1 is the pivot integer since: 1 = 1.
Example 3:

Input: n = 4
Output: -1
Explanation: It can be proved that no such integer exist.

A
class Solution:
    def pivotInteger(self, n: int) -> int:
        l, r = 1, n
        while l <= r:
            m = l + (r - l) // 2
            totalSum = n * (n + 1) // 2
            leftSum = m * (m + 1) // 2
            rightSum = totalSum - leftSum + m

            if leftSum == rightSum:
                return m
            elif leftSum < rightSum:
                l = m + 1
            else:
                r = m - 1
        return -1
        #O(log n)
        #O(1)
21
Q

Merge In Between Linked Lists

ou are given two linked lists: list1 and list2 of sizes n and m respectively.

Remove list1’s nodes from the ath node to the bth node, and put list2 in their place.

The blue edges and nodes in the following figure indicate the result:

Build the result list and return its head.

Input: list1 = [10,1,13,6,9,5], a = 3, b = 4, list2 = [1000000,1000001,1000002]
Output: [10,1,13,1000000,1000001,1000002,5]
Explanation: We remove the nodes 3 and 4 and put the entire list2 in their place. The blue edges and nodes in the above figure indicate the result.

A

Definition for singly-linked list.

# Definition for singly-linked list.
# class ListNode:
#     def \_\_init\_\_(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeInBetween(self, list1: ListNode, a: int, b: int, list2: ListNode) -> ListNode:
        dummy = ListNode()
        dummy.next = list1
        cur = dummy
        for i in range(a):
            cur = cur.next
        second = cur
        #Second is now right before where we need to donate
        for j in range(b - a + 1): #4-3 + 1 = 2. So [0, 1]
            second = second.next
        #Second is now at the tail of the section to be removed. So the 
        #node after this is the one we connect new list2's tail to.
        cur.next = list2
        tail = list2
        while tail and tail.next:
            tail = tail.next
        tail.next = second.next
        return dummy.next
        #O(n)
        #O(1)
        
22
Q

Subarray Product Less Than K

Given an array of integers nums and an integer k, return the number of contiguous subarrays where the product of all the elements in the subarray is strictly less than k.

Input: nums = [10,5,2,6], k = 100
Output: 8
Explanation: The 8 subarrays that have product less than 100 are:
[10], [5], [2], [6], [10, 5], [5, 2], [2, 6], [5, 2, 6]
Note that [10, 5, 2] is not included as the product of 100 is not strictly less than k.

A
class Solution:
    def numSubarrayProductLessThanK(self, nums: List[int], k: int) -> int:
        if k <= 1: #no subarray possible. True for [1, 1, 1] and k = 1 too.
            return 0
        res = 0
        product = 1
        l = 0
        for r in range(len(nums)):
            product *= nums[r]
            while product >= k:
                product /= nums[l]
                l += 1
            res += r - l + 1 #the total of valid subarrays is computed by adding size of this window
            #Example #1 nums = [10, 5], k = 100
            #First iteration: is 10, so res = 1
            #Second iteration: is 50, so res+=2 -> res = 3
            #[10], [5], [10 ,5] matches
            #r - l + 1 works because let's say we need to shrink:
            #Example #2: [10, 5], k = 49
            #First iteration: is 10, res = 1
            #Second iteration: is 50, so l and r match at 5. Therefore, res += 1
            #So res = 2 in this case [10], [5]
        return res
        #O(n)
        #O(1)
        
23
Q

Length of Longest Subarray With at Most K Frequency
You are given an integer array nums and an integer k.

The frequency of an element x is the number of times it occurs in an array.

An array is called good if the frequency of each element in this array is less than or equal to k.

Return the length of the longest good subarray of nums.

A subarray is a contiguous non-empty sequence of elements within an array.

Input: nums = [1,2,3,1,2,3,1,2], k = 2
Output: 6
Explanation: The longest possible good subarray is [1,2,3,1,2,3] since the values 1, 2, and 3 occur at most twice in this subarray. Note that the subarrays [2,3,1,2,3,1] and [3,1,2,3,1,2] are also good.
It can be shown that there are no good subarrays with length more than 6.

A
class Solution:
    def maxSubarrayLength(self, nums: List[int], k: int) -> int:
        res = 0
        counts = defaultdict(int)

        l = 0
        for r in range(len(nums)):
            counts[nums[r]] += 1
            while counts[nums[r]] > k:
                counts[nums[l]] -= 1
                l += 1
            res = max(res, r - l + 1)
        return res
        #O(n)
        #O(n) #for the unique elements
24
Q

Count Subarrays Where Max Element Appears at Least K Times
ou are given an integer array nums and a positive integer k.

Return the number of subarrays where the maximum element of nums appears at least k times in that subarray.

A subarray is a contiguous sequence of elements within an array.
Input: nums = [1,3,2,3,3], k = 2
Output: 6
Explanation: The subarrays that contain the element 3 at least 2 times are: [1,3,2,3], [1,3,2,3,3], [3,2,3], [3,2,3,3], [2,3,3] and [3,3].

A
class Solution:
    def countSubarrays(self, nums: List[int], k: int) -> int:
        maxVal = max(nums)
        res = 0
        l = 0
        maxCount = 0
        for r in range(len(nums)):
            if nums[r] == maxVal:
                maxCount += 1
            #Given some anchor point r, find all L subarrays
            #that are valid
            while maxCount == k:
                if nums[l] == maxVal:
                    maxCount -= 1
                l += 1
            #Let's say l ends at i = 2. So subarray starting
            #at 0 and 1 are valid! Since those are bigger
            #and have not exited the while loop
            res += l
        return res
        #O(n)
        #O(1)
            
25
Q

Subarrays with K Different Integers

Given an integer array nums and an integer k, return the number of good subarrays of nums.

A good array is an array where the number of different integers in that array is exactly k.

For example, [1,2,3,1,2] has 3 different integers: 1, 2, and 3.
A subarray is a contiguous part of an array.

Input: nums = [1,2,1,2,3], k = 2
Output: 7
Explanation: Subarrays formed with exactly 2 different integers: [1,2], [2,1], [1,2], [2,3], [1,2,1], [2,1,2], [1,2,1,2]

A
class Solution:
    def subarraysWithKDistinct(self, nums: List[int], k: int) -> int:
        #count number of subarrays at least K.
        def helper(K):
            counts = defaultdict(int)
            l = 0
            res = 0
            for r in range(len(nums)):
                counts[nums[r]] += 1
                while len(counts) > K:
                    counts[nums[l]] -= 1
                    if counts[nums[l]] == 0:
                        del counts[nums[l]]
                    l += 1
                res += r - l + 1 #counting subarrays
                #Example: [1 2] add [3]. We created 3 subarrays: 123, 23, 3
            return res
        return helper(k) - helper(k - 1) #num subarrays at least k - num subarrays at least k - 1 -> exactly k
        #O(n)
        #O(n) #hashmap
26
Q

Length of Last Word

Given a string s consisting of words and spaces, return the length of the last word in the string.

A word is a maximal
substring
consisting of non-space characters only.

Input: s = “ fly me to the moon “
Output: 4
Explanation: The last word is “moon” with length 4.

A
class Solution:
    def lengthOfLastWord(self, s: str) -> int:
        # return len(s.split()[-1])
        # #O(n)
        # #O(n)
        s = s.strip()
        res = 0
        for r in range(len(s) - 1, -1, -1):
            if s[r] == " ":
                break
            res += 1
        return res
        #O(n)
        #O(1)
27
Q

Maximum Nesting Depth of the Parentheses

A string is a valid parentheses string (denoted VPS) if it meets one of the following:

It is an empty string “”, or a single character not equal to “(“ or “)”,
It can be written as AB (A concatenated with B), where A and B are VPS’s, or
It can be written as (A), where A is a VPS.
We can similarly define the nesting depth depth(S) of any VPS S as follows:

depth(“”) = 0
depth(C) = 0, where C is a string with a single character not equal to “(“ or “)”.
depth(A + B) = max(depth(A), depth(B)), where A and B are VPS’s.
depth(“(“ + A + “)”) = 1 + depth(A), where A is a VPS.
For example, “”, “()()”, and “()(()())” are VPS’s (with nesting depths 0, 1, and 2), and “)(“ and “(()” are not VPS’s.

Given a VPS represented as string s, return the nesting depth of s.

Input: s = “(1+(2*3)+((8)/4))+1”
Output: 3
Explanation: Digit 8 is inside of 3 nested parentheses in the string.

Input: s = “(1)+((2))+(((3)))”
Output: 3

A
class Solution:
    def maxDepth(self, s: str) -> int:
        maxDepth = 0
        curDepth = 0
        for c in s:
            if c == "(":
                curDepth += 1
                maxDepth = max(maxDepth, curDepth)
            elif c == ")":
                curDepth -= 1
        return maxDepth
        #O(n)
        #O(1)
28
Q
A