# LeetCode Summary :::spoiler Table of Contents [TOC] ::: ## bebo1010 -- python ### Sorting #### One Line Sorting :::spoiler Sort by another Dictionary ```python sorted(nums, key = lambda element: key_dict[element]) ``` ::: :::spoiler Sort by Height ```python [name for name, height in sorted(zip(names, heights), key=lambda item: item[1], reverse=True)] ``` ::: :::spoiler Sort by Most Profit ```python difficulty, profit = zip(*sorted(zip(difficulty, profit), key=lambda i: i[1], reverse=True)) ``` ::: :::spoiler Sort by Occurrences then Elements [1636. Sort Array by Increasing Frequency](https://leetcode.com/problems/sort-array-by-increasing-frequency) Sort by occurences in ascending order, then sort by elements themself in descending order ```python= from collections import Counter occurrences = Counter(nums) # a dict that stores occurrences, {element: occurrence} sorted(nums, key=lambda element: (occurrences[element], -element)) ``` ::: #### Radix Sort [912. Sort an Array](https://leetcode.com/problems/sort-an-array) :::spoiler 2-Based Radix Sort ```python= def counting_sort(arr, exp, min_value): n = len(arr) output = [0] * n # Output array count = [0] * 2 # Counting array for base 2 (0 and 1) # Store count of occurrences in count[] for i in range(n): index = ((arr[i] - min_value) >> exp) & 1 count[index] += 1 # Change count[i] so that count[i] now contains actual # position of this digit in output[] count[1] += count[0] # Build the output array i = n - 1 while i >= 0: index = ((arr[i] - min_value) >> exp) & 1 output[count[index] - 1] = arr[i] count[index] -= 1 i -= 1 # Copy the output array to arr[], so that arr now # contains sorted numbers according to current digit for i in range(n): arr[i] = output[i] def radix_sort(arr): # Find the minimum and maximum number to know the range min_value = min(arr) max_num = max(arr) - min_value exp = 0 while (max_num >> exp) > 0: counting_sort(arr, exp, min_value) exp += 1 ``` ::: ### Graph #### Dijkstra's Algorithm [1334. Find the City With the Smallest Number of Neighbors at a Threshold Distance](https://leetcode.com/problems/find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance/) [Dijkstra's Algorithm Reference](https://medium.com/%E6%8A%80%E8%A1%93%E7%AD%86%E8%A8%98/%E5%9F%BA%E7%A4%8E%E6%BC%94%E7%AE%97%E6%B3%95%E7%B3%BB%E5%88%97-graph-%E8%B3%87%E6%96%99%E7%B5%90%E6%A7%8B%E8%88%87dijkstras-algorithm-6134f62c1fc2) :::spoiler Dijkstra's Algorithm for Directed Graph Implementation ```python= def dijkstra_algorithm(n: int, starting_point: int, edges: List[List[int]]) -> list[int]: visited = [False] * n cost = [float('inf')] * n prev_node = [-1] * n cost[starting_point] = 0 current_point = starting_point while not all(visited): for edge in edges: start, end, edge_cost = edge if current_point == start and not visited[end]: new_cost = cost[current_point] + edge_cost if new_cost < cost[end]: cost[end] = new_cost prev_node[end] = start visited[current_point] = True min_cost = float('inf') next_point = -1 for i in range(n): if not visited[i] and cost[i] < min_cost: min_cost = cost[i] next_point = i if next_point == -1: break current_point = next_point return cost ``` ::: :::spoiler Dijkstra's Algorithm for Undirected Graph Implementation ```python= def dijkstra_algorithm(n: int, starting_point: int, edges: List[List[int]]) -> list[int]: visited = [False] * n cost = [float('inf')] * n prev_node = [-1] * n cost[starting_point] = 0 current_point = starting_point bidirectional_edges = edges + [[end, start, edge_cost] for start, end, edge_cost in edges] while not all(visited): for edge in bidirectional_edges: start, end, edge_cost = edge if current_point == start and not visited[end]: new_cost = cost[current_point] + edge_cost if new_cost < cost[end]: cost[end] = new_cost prev_node[end] = start visited[current_point] = True min_cost = float('inf') next_point = -1 for i in range(n): if not visited[i] and cost[i] < min_cost: min_cost = cost[i] next_point = i if next_point == -1: break current_point = next_point return cost ``` ::: ### Tree #### Character Trie [648. Replace Words](https://leetcode.com/problems/replace-words) :::spoiler Character Trie Implementation Path of tree is represented by the character, initialize a node per path. ```python= class TrieNode: def __init__(self): self.children = {} self.is_end_of_word = False class Trie: def __init__(self): self.root = TrieNode() def insert(self, word: str): node = self.root for char in word: if node.is_end_of_word: return if char not in node.children: node.children[char] = TrieNode() node = node.children[char] node.is_end_of_word = True def search_shortest_prefix(self, word: str) -> str: node = self.root prefix = "" for char in word: if char not in node.children: break prefix += char node = node.children[char] if node.is_end_of_word: return prefix return word ``` ::: #### Depth First Search [1038. Binary Search Tree to Greater Sum Tree](https://leetcode.com/problems/binary-search-tree-to-greater-sum-tree) :::spoiler Reverse In-order Depth First Search Implementation ```python= # 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 def right_first_dfs(self, current_node: TreeNode): if current_node is None: return self.right_first_dfs(current_node.right) self.current_sum += current_node.val current_node.val = self.current_sum self.right_first_dfs(current_node.left) ``` ::: [1110. Delete Nodes And Return Forest](https://leetcode.com/problems/delete-nodes-and-return-forest) :::spoiler Post-order Depth First Search Implementation ```python= def depth_first_post_order(self, root: TreeNode, delete_flag: bool): if root is None: return None if root.val in self.to_delete_set: to_be_deleted = True else: to_be_deleted = False root.left = self.depth_first_post_order(root.left, to_be_deleted) root.right = self.depth_first_post_order(root.right, to_be_deleted) if not to_be_deleted and delete_flag: self.root_list.append(root) if to_be_deleted: return None else: return root ``` ::: [1382. Balance a Binary Search Tree](https://leetcode.com/problems/balance-a-binary-search-tree) :::spoiler In-order Depth First Travesal Implementation ```python= # 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 def in_order_traversal(self, current_node: TreeNode): if current_node == None: return None self.in_order_traversal(current_node.left) self.values.append(current_node.val) self.in_order_traversal(current_node.right) ``` ::: :::spoiler Build Balanced Binary Search Tree from Array Implementation ```python= def build_balanced_BST(self, values: list) -> TreeNode: if len(values) == 0: return None mid_point = int(len(values) >> 1) root = TreeNode(values[mid_point]) root.left = self.build_balanced_BST(values[:mid_point]) root.right = self.build_balanced_BST(values[mid_point+1:]) return root ``` ::: ### Stack #### Find Score by Removing Substring [1717. Maximum Score From Removing Substrings](https://leetcode.com/problems/maximum-score-from-removing-substrings) :::spoiler Remove Substring using Stack Implementation ```python= def find_ab_scores(self, s: str, score: int) -> [str, int]: partial_score = 0 stack = [] for c in s: if c != 'b': stack.append(c) else: if len(stack) > 0: if stack[-1] == 'a': print("added x") partial_score += score stack.pop() else: stack.append(c) else: stack.append(c) # stack.reverse() return "".join(stack), partial_score ``` ::: ### Heap Queue [703. Kth Largest Element in a Stream](https://leetcode.com/problems/kth-largest-element-in-a-stream) [Python Heap Queue Algorithm Document](https://docs.python.org/3/library/heapq.html) :::spoiler Heap Queue Details Initialize the heap with a empty list `x = []` or convert a list with `heapq.heapify(x)` `heap[0]` is the smallest item in the heap. - `heapq.heappush(heap, item)` Push the value `item` onto the heap - `heapq.heappop(heap)` Pop the smallest `item` from the heap If the `heap` is empty, `IndexError` is raised To access the smallest `item` without popping it, use `heap[0]` - `heapq.heappushpop(heap, item)` Push the value `item` onto the heap, then pop and return the smallest `item` from the heap More efficient than `heapq.heappush()` then `heapq.heappop()` - `heapq.heapreplace(heap, item)` Pop and return the smallest `item` from the heap, then push the value `item` onto the heap If the `heap` is empty, `IndexError` is raised More efficient than `heapq.heappop()` then `heapq.heappush()` Heap elements can also be tuples. ```python >>> h = [] >>> heappush(h, (5, 'write code')) >>> heappush(h, (7, 'release product')) >>> heappush(h, (1, 'write spec')) >>> heappush(h, (3, 'create tests')) >>> heappop(h) (1, 'write spec') ``` ::: ::: spoiler Example for Heap Sort ```python= def heapsort(iterable): h = [] for value in iterable: heappush(h, value) return [heappop(h) for i in range(len(h))] ... >>> heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0]) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ``` ::: ### Miscellany #### Pascal Triangle [118. Pascal's Triangle](https://leetcode.com/problems/pascals-triangle) :::spoiler Pascal Triangle Implementation ```python= def generate(numRows: int) -> List[List[int]]: full_triangle = [[1]] # base case for row in range(2, numRows + 1): prev_row = full_triangle[row - 2] current_row = [] middle_point = row >> 1 element = 1 for index in range(middle_point): if index == 0: current_row.insert(0, 1) current_row.insert(-1, 1) else: element = prev_row[index - 1] + prev_row[index] current_row.insert(index, element) current_row.insert(-index, element) if row & 0x01 == 1: element = prev_row[middle_point - 1] + prev_row[middle_point] current_row.insert(middle_point, element) full_triangle.append(current_row) return full_triangle ``` ::: #### Modulo Sums [523. Continuous Subarray Sum](https://leetcode.com/problems/continuous-subarray-sum) :::spoiler Modulo Sums Explanation The sum of any array can be rewritten as follow: $\text{sum}(:j) = \text{sum}(:i) + \text{sum}(i:j)$ for all $i < j$ For a subarray with size greater than 1 to exist such that the sum of its elements is `divisivble by k`, $\text{sum}(i:j) \% k$ must equal to 0 for some $i < j - 1$, the reason for $j - 1$ is because the length of subarray must be greater than or equal to 2 If we modules both sides of the above equation: $\text{sum}(:j) \% k = [\text{sum}(:i) + \text{sum}(i:j)] \% k$ $\Rightarrow \text{sum}(:j) \% k = [\text{sum}(:i) \%k + \text{sum}(i:j) \%k] \% k$ $\Rightarrow \text{sum}(:j) \% k = \text{sum}(:i) \%k$ Find the $i$ and $j$ that satisfy this condition ::: #### Sliding Window [2134. Minimum Swaps to Group All 1's Together II](https://leetcode.com/problems/minimum-swaps-to-group-all-1s-together-ii) :::spoiler Techniques for using Sliding Window on Circular Array Assume the window size is `sliding_window_size`. 1. Use modulation to calculate index, quite slow ```python= nums = [1, 2, 3] sliding_window_size = 2 for i in range(0, len(appended_nums) - k + 1): subarray = [nums[(i + j) % len(nums)] for j in range(sliding_window_size)] ... ``` 2. Append the first `k` elements to the end of array, faster ```python= nums = [1, 2, 3] sliding_window_size = 2 appended_nums = nums + nums[:sliding_window_size] for i in range(0, len(appended_nums) - sliding_window_size + 1): subarray = appended_nums[i:i + sliding_window_size] ... ``` ::: #### Split String into Chunks [273. Integer to English Words](https://leetcode.com/problems/integer-to-english-words) Split the numbers from least significant digits into chunks :::spoiler Spliting Implementation ```pyhton= def split_into_chunks(number, chunk_size=3): str_number = str(number)[::-1] chunks = [str_number[i:i+chunk_size] for i in range(0, len(str_number), chunk_size)] chunks = [chunk[::-1] for chunk in chunks] return chunks ``` ::: #### Factorization [650. 2 Keys Keyboard](https://leetcode.com/problems/2-keys-keyboard/description) :::danger How can this problem be reduced into a factorization problem? ::: :::spoiler Factorization Implementation The first part check if `n` is 1 (special case). The second part check the multiple of 2. The third part check other prime factors. The last part is when the remaining of `n` is a prime factor, add it to the list. ```pyhton= def get_prime_factors(n: int) -> list: if n == 1: return [1] factors = [] while n % 2 == 0: factors.append(2) n //= 2 for i in range(3, int(n**0.5) + 1, 2): while n % i == 0: factors.append(i) n //= i if n > 2: factors.append(n) return factors ``` ::: :::spoiler Leetcode Editorial ![messageImage_1724049701304](https://hackmd.io/_uploads/BywhKDgsR.jpg) ```python= class Solution: def minSteps(self, n: int) -> int: if n == 1: return 0 self.n = n self.memo = [[0] * (n // 2 + 1) for _ in range(n + 1)] return 1 + self._min_steps_helper(1, 1) def _min_steps_helper(self, curr_len: int, paste_len: int) -> int: if curr_len == self.n: return 0 if curr_len > self.n: return 1000 # return result if it has been calculated already if self.memo[curr_len][paste_len] != 0: return self.memo[curr_len][paste_len] opt1 = 1 + self._min_steps_helper(curr_len + paste_len, paste_len) opt2 = 2 + self._min_steps_helper(curr_len * 2, curr_len) self.memo[curr_len][paste_len] = min(opt1, opt2) return self.memo[curr_len][paste_len] ``` ::: #### Bit-Wise Complement [476. Number Complement](https://leetcode.com/problems/number-complement) :::spoiler Bit-by-Bit Complement 1. Get the binary representation (in `str`) of original number `num` by `bin()`. 2. Complement the bits. The return value of `bin()` would contain `0b` in them. For example `bin(5)` returns `0b101` $O(n)$ solution where $n$ is the number of bits used to represent the number ```python= def findComplement(self, num: int) -> int: new_str = "0b" binary_string = bin(num) for bit_index in range(2, len(binary_string)): bit = binary_string[bit_index] new_str += "0" if bit == "1" else "1" return int(new_str, 2) ``` ::: :::spoiler Complement with Exclusive OR 1. Get the bit length of original number `num` by `bit_length()`. 2. Generate the mask. 3. Complement the number with the mask and XOR operation. The return value of `bit_length()` is the number of bits used to represent the number. For example `bin(5)` returns `3` (`0b101` takes 3 bits to represent). $O(log(n))$ solution where $n$ is the number of bits used to represent the number ```python= def findComplement(self, num: int) -> int: bit_length = num.bit_length() mask = (1 << bit_length) - 1 return num ^ mask ``` ::: #### Greatest Common Divisor [2807. Insert Greatest Common Divisors in Linked List](https://leetcode.com/problems/insert-greatest-common-divisors-in-linked-list) [Euclidean Algorithm](https://en.wikipedia.org/wiki/Euclidean_algorithm) :::spoiler Find GCD with Euclidean Algorithm Implementation ```python= def gcd(a, b): while b: a, b = b, a % b return a ``` ::: ## bebo1010 -- C++ ### Circular Deque [641. Design Circular Deque](https://leetcode.com/problems/design-circular-deque) :::spoiler Circular Deque Implementation `start_index` and `end_index` are the indices that's ready for the next insertion. Thus having to recalculate index again when trying to `getFront()` and `getRear()`. ```c++= class MyCircularDeque { public: MyCircularDeque(int k) : max_length(k){ deque.resize(k, -1); } bool insertFront(int value) { if(deque_length == max_length){ return false; } deque[start_index] = value; start_index = (start_index - 1 + max_length) % max_length; deque_length++; return true; } bool insertLast(int value) { if(deque_length == max_length){ return false; } deque[end_index] = value; end_index = (end_index + 1) % max_length; deque_length++; return true; } bool deleteFront() { if(deque_length == 0){ return false; } start_index = (start_index + 1) % max_length; deque[start_index] = -1; deque_length--; return true; } bool deleteLast() { if(deque_length == 0){ return false; } end_index = (end_index - 1 + max_length) % max_length; deque[end_index] = -1; deque_length--; return true; } int getFront() { if(deque_length == 0){ return -1; } int front_index = (start_index + 1) % max_length; return deque[front_index]; } int getRear() { if(deque_length == 0){ return -1; } int rear_index = (end_index - 1 + max_length) % max_length; return deque[rear_index]; } bool isEmpty() { return deque_length == 0; } bool isFull() { return deque_length == max_length; } private: vector<int> deque; const int max_length; int deque_length = 0; int start_index = 0; int end_index = 1; }; /** * Your MyCircularDeque object will be instantiated and called as such: * MyCircularDeque* obj = new MyCircularDeque(k); * bool param_1 = obj->insertFront(value); * bool param_2 = obj->insertLast(value); * bool param_3 = obj->deleteFront(); * bool param_4 = obj->deleteLast(); * int param_5 = obj->getFront(); * int param_6 = obj->getRear(); * bool param_7 = obj->isEmpty(); * bool param_8 = obj->isFull(); */ ``` ::: ## bebo1010 -- C ### Array #### Binary Search [1331. Rank Transform of an Array](https://leetcode.com/problems/rank-transform-of-an-array) Using basic `Linear Search` would trigger TLE at this question. Use Binary Search instead. :::spoiler Binary Search Implementation ```c= int binary_search(int element, int *array, int array_length){ int left_index = 0; int right_index = array_length; int middle_index; while(left_index < right_index){ middle_index = left_index + (right_index - left_index) / 2; if(element == array[middle_index]){ return middle_index; } else if(element > array[middle_index]){ left_index = middle_index; } else{ right_index = middle_index; } } return -1; } ``` ::: ### Bit-wise Operation #### Remove first set bit from least significant bit ```c= x = x & (x - 1); ``` This can be used to get how many set bits are in a number, for example: ```c= count = 0; while(x > 0){ count++; x = x & (x - 1); } ``` ## sushake -- c ### String #### string to array ```c= char array1[] = source; char* array2 = target; //find length int length = strlen(source); ``` ### Graph #### Dijkstra's Algorithm [1334. Find the City With the Smallest Number of Neighbors at a Threshold Distance](https://leetcode.com/problems/find-the-city-with-the-smallest-number-of-neighbors-at-a-threshold-distance/) - [Dijkstra's Algorithm Reference](https://medium.com/%E6%8A%80%E8%A1%93%E7%AD%86%E8%A8%98/%E5%9F%BA%E7%A4%8E%E6%BC%94%E7%AE%97%E6%B3%95%E7%B3%BB%E5%88%97-graph-%E8%B3%87%E6%96%99%E7%B5%90%E6%A7%8B%E8%88%87dijkstras-algorithm-6134f62c1fc2) :::spoiler Dijkstra's Algorithm for Undirected Graph Implementation ```c= int dijkstra(int** table, int start, int n) { int* distance = (int*)malloc(sizeof(int) * n); for(int i = 0; i < n; i++) distance[i] = stable[start][i]; int* book = (int*)malloc(sizeof(int) * n); memset(book, 0, sizeof(int) * n); book[city] = 1; for(int i = 0; i < n; i++) { int min = INT_MAX; int id = -1; for(int j = 0; j < n; j++) { if(book[j] == 0 && distance[j] < min) { min = distance[j]; id = j; } } if (id == -1) break; book[id] = 1; for(int j = 0; j < n; j++) { if(book[j] == 0 && table[id][j] != INT_MAX && distance[j] > distance[id] + road[id][j]) distance[j] = distance[id] + road[id][j]; } } } ``` ::: - [2976. Minimum Cost to Convert String I](https://leetcode.com/problems/minimum-cost-to-convert-string-i/description/?envType=daily-question&envId=2024-07-27) 這題會有時間限制,我的策略為將所有 distance 儲存在 26*26 表格裡,這樣就不會有重複找的問題。**這題有個噁心點: 他給的 cost 有重複的,需判斷哪個比較小。** ### Sort #### quicksort :::spoiler quicksort in C library ```c= /* The comparison function must return an integer less than, * equal to, or greater than zero if the first argument is * considered to be respectively less than, equal to, or greater * than the second. If two members compare as equal, their * order in the sorted array is undefined. */ int cmpfunc (const void * a, const void * b) { return ( *(int*)a - *(int*)b ); } int cmpstring(const void *p1, const void *p2) { /* The actual arguments to this function are "pointers to pointers to char", but strcmp(3) arguments are "pointers to char", hence the following cast plus dereference */ return strcmp(* (char * const *) p1, * (char * const *) p2); } qsort(array, arraySize, sizeof(int), cmpfunc); ``` ::: ### Top Interview 150 #### Array / String - [88. Merge Sorted Array](https://leetcode.com/problems/merge-sorted-array/description/?envType=study-plan-v2&envId=top-interview-150) 因為答案會儲存在 array1 當中,所以節省記憶體空間的方法為從尾端開始填數字。 - [26. Remove Duplicates from Sorted Array](https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/?envType=study-plan-v2&envId=top-interview-150) :::spoiler [In-place algorithm](https://www.geeksforgeeks.org/in-place-algorithm/) ```c= int removeDuplicates(int* nums, int numsSize) { int i = 0; int j = 0; while(i < numsSize) { int val = nums[i]; j +=1; while(j < numsSize && nums[j] == val) { j += 1; } i +=1; if(j < numsSize) nums[i] = nums[j]; else break; } return i; } ``` ::: - [55. Jump Game](https://leetcode.com/problems/jump-game/description/?envType=study-plan-v2&envId=top-interview-150) 這題我是參照他人的[解法](https://leetcode.com/problems/jump-game/solutions/4534808/super-simple-intuitive-8-line-python-solution-beats-99-92-of-users/?envType=study-plan-v2&envId=top-interview-150) - [12. Integer to Roman](https://leetcode.com/problems/integer-to-roman/description/?envType=study-plan-v2&envId=top-interview-150) 這題本來很笨的用 if 迴圈慢慢把 string 找出來,chatGPT 最後整理的程式碼,供參。順便紀錄怎麼增加 string 元素(strcat)。 :::spoiler string add item ```c= char* intToRoman(int num) { const char* roman_numerals[] = { "M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}; const int values[] = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; char* output = (char*)malloc(20); output[0] = '\0'; int i = 0; while (num > 0) { while (num >= values[i]) { strcat(output, roman_numerals[i]); num -= values[i]; } i++; } return output; } ``` ::: - [14. Longest Common Prefix](https://leetcode.com/problems/longest-common-prefix/description/?envType=study-plan-v2&envId=top-interview-150) 紀錄如何使用 strcpy 以及 strncpy ,詳細可參考這篇[文章](https://blog.csdn.net/weixin_37800531/article/details/141947145)講述差異性 :::spoiler string copy item ```c= char* longestCommonPrefix(char** strs, int strsSize) { if(strsSize == 0) return ""; char* output = strs[0]; int length = strlen(output); for(int i = 1; i < strsSize; i++){ char* word = strs[i]; int len = strlen(word); for(int j = 0; j < length; j++){ if(len == 0 || output[j] != word[j]){ length = j; break; } len--; } if(length == 0) return ""; } char* final = (char*)malloc(sizeof(char) * (length + 1)); strncpy(final, output, length); final[length] = '\0'; //這個要自己加!!! return final; } ``` ::: #### Two Pointers - [15. 3Sum](https://leetcode.com/problems/3sum/description/?envType=study-plan-v2&envId=top-interview-150) **這題很重要,要會!!!** 這題我是看解答的,思路如下。 先從小到大排列,第一個迴圈用來固定第一個變數,這樣就是 2sum 的題目。 再來將第二個變數設為第一個變數位置加一,第三個變數位置設為佇列尾端,然後將三數相加跟零做比較 : 比零大表示第三個變數太大,往左移;比零小表示第二個變數太小,往右移。 :::spoiler 學起來如何使用 qsort ```c= int cmpfunc (const void * a, const void * b) { return ( *(int*)a - *(int*)b ); } int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) { qsort(nums, numsSize, sizeof(int), cmpfunc); *returnSize = 0; int** output = (int**)malloc(sizeof(int*) * (numsSize * numsSize)); for(int i = 0; i < numsSize - 2; i++) { if (i > 0 && nums[i] == nums[i - 1]) continue;//skip duplicate int second = i + 1; int third = numsSize - 1; while(second < third) { int count = nums[i] + nums[second] + nums[third]; if(count == 0) { output[*returnSize] = (int*)malloc(sizeof(int) * 3); output[*returnSize][0] = nums[i]; output[*returnSize][1] = nums[second]; output[*returnSize][2] = nums[third]; (*returnSize) += 1; // Skip duplicate 'left' and 'right' values while (second < third && nums[second] == nums[second + 1]) second++; while (second < third && nums[third] == nums[third - 1]) third--; second++; third--; }else if(count > 0) third --; else second++; } } *returnColumnSizes = (int*)malloc(sizeof(int) * (*returnSize)); for (int i = 0; i < *returnSize; i++) { (*returnColumnSizes)[i] = 3; } return output; } ``` ::: - [3. Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/description/?envType=study-plan-v2&envId=top-interview-150) 這題有個重點,s consists of English letters, digits, symbols and spaces. 所以標點符號跟空白都需要包含。根據 ASCII 可顯示字元編號範圍是32-126(0x20-0x7E),共95個字元。