遍歷 nums 中的所有元素,對於每個元素 x ,若 cnt 的值為 0,則將 x 的值賦予 candidate ,隨後判斷 x:
若 x 與 candidate 相等,則計數器 cnt 的值增加 1;
若 x 與 candidate 不等,則計數器 cnt 的值減少 1。
當 cnt 的值為 0 時,存在兩種情況:
candidate 不是多數元素,則顯然需要嘗試選擇 x 作為新的候選人;
candidate 是多數元素,則捨去 x 之前的所有元素,candidate 仍然是多數元素,最終仍會被選為候選人,不影響結果。
最終的 candidate 即為整個陣列的多數元素。
時間複雜度:O(n),其中 n 為陣列的長度。
空間複雜度:O(1)。
1 2 3 4 5 6 7
classSolution: defmajorityElement(self, nums: List[int]) -> int: cnt = defaultdict(int) for num in nums: cnt[num] += 1 if cnt[num] > len(nums) // 2: return num
1 2 3 4 5 6 7 8 9
classSolution: defmajorityElement(self, nums: List[int]) -> int: cnt = 0 candidate = None for num in nums: if cnt == 0: candidate = num cnt += 1if num == candidate else -1 return candidate
給定一個二維字串陣列 words ,返回陣列中的 第一個回文(Palindromic)字串。如果不存在滿足要求的字串,則返回一個空字串 ""。
思路
定義一個函數 isPalindrome 來判斷字串是否為回文字串,並對每個字串進行判斷即可。
時間複雜度:O(n⋅m),其中 n 為陣列的長度,m 為陣列中字串的平均長度。
空間複雜度:O(1)。
1 2 3 4 5 6 7 8 9 10 11 12
classSolution: deffirstPalindrome(self, words: List[str]) -> str: defisPalindrome(s): n = len(s) for i inrange(n//2): if s[i] != s[n-1-i]: returnFalse returnTrue for word in words: if isPalindrome(word): return word return""
給定一個Binary Tree的根節點 root ,返回其 層序遍歷(Level Order Traversal) (即逐層地,從左到右訪問所有節點) 的結果。
思路:BFS
level order traversal 即使用BFS進行遍歷,維護一個 queue 來存放每一層的節點,並且記錄每一層的節點的值。
時間複雜度:O(n),其中 n 為二叉樹的節點數。
空間複雜度:O(n)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution: deflevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]: ans = [] ifnot root: return ans q = deque([root]) while q: cur = [] for _ inrange(len(q)): node = q.popleft() cur.append(node.val) if node.left: q.append(node.left) if node.right: q.append(node.right) ans.append(cur) return ans
classSolution: defrearrangeArray(self, nums: List[int]) -> List[int]: n = len(nums) ans = [0] * n pos, neg = 0, 0# Two pointers for i inrange(n//2): while pos < n and nums[pos] < 0: pos += 1 while neg < n and nums[neg] > 0: neg += 1 ans[i*2] = nums[pos] ans[i*2+1] = nums[neg] pos += 1 neg += 1 return ans
classSolution: deflargestPerimeter(self, nums: List[int]) -> int: n = len(nums) nums.sort() # pre = list(accumulate(nums, initial=0)) s = sum(nums) for i inrange(n - 1, 1, -1): # if pre[i] > nums[i]: # return pre[i] + nums[i] if s > 2 * nums[i]: # s - nums[i] > nums[i] return s s -= nums[i] return -1
classSolution: deffindLeastNumOfUniqueInts(self, arr: List[int], k: int) -> int: cnt = Counter(arr) keys = sorted(cnt.keys(), key=cnt.get) i = 0 while k: if k >= cnt[keys[i]]: k -= cnt[keys[i]] i += 1 else: break returnlen(keys) - i
classSolution: defpreorder(self, root: 'Node') -> List[int]: defdfs(node): res = [] if node isNone: return res res = [node.val] for child in node.children: res += dfs(child) return res return dfs(root)
在上述操作後,不管遇到哪種情況,都可以直接令該會議的結束時間 ed=t+d ,其中 d 為會議持續時間,t 為最早結束的會議室的結束時間。
最後,我們只需遍歷每個會議室的使用次數,找到使用次數最多的會議室即可。
時間複雜度:O(mlogm),其中 m 為 meetings 的長度,為排序的時間複雜度。
空間複雜度:O(n)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution: defmostBooked(self, n: int, meetings: List[List[int]]) -> int: meetings.sort() # 依照會議開始時間排序 cnt = [0] * (n) # 每個會議室的使用次數 hp = [(0, i) for i inrange(n)] # 維護每個會議室的結束時間,初始化為0,表示每個會議室在時間0時都是可用的 for st, ed in meetings: d = ed - st # 會議持續時間 while hp and hp[0][0] < st: # 為滿足規則1,可將該會議室的結束時間更新為當前會議的開始時間 _, tmp_idx = heappop(hp) heappush(hp, (st, tmp_idx)) t, idx = heappop(hp) # 取出最早結束的會議室編號 ed = t + d # 更新該會議室的結束時間 heappush(hp, (ed, idx)) # 將該會議的結束時間和使用的會議室編號加入heap cnt[idx] += 1 ans = 0 for i, v inenumerate(cnt): if v > cnt[ans]: ans = i return ans
classSolution: defpostorder(self, root: 'Node') -> List[int]: defdfs(node): res = [] if node isNone: return res res = [] for child in node.children: res += dfs(child) res.append(node.val) return res return dfs(root)
時間複雜度:O(n2),其中 n 為二叉樹的節點數,每次查找 root 在 inorder 中的位置需要 O(n) 的時間。
空間複雜度:O(n2),最壞情況下,每次遞迴都需要 O(n) 的空間。
1 2 3 4 5 6 7 8 9
classSolution: defbuildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]: iflen(preorder) == 0: returnNone root = TreeNode(preorder[0]) idx = inorder.index(preorder[0]) # let idx be the index of root in inorder, which is also the size of left subtree root.left = self.buildTree(preorder[1:idx+1], inorder[:idx]) root.right = self.buildTree(preorder[idx+1:], inorder[idx+1:]) return root