喜刷刷3

अब Quizwiz के साथ अपने होमवर्क और परीक्षाओं को एस करें!

[LeetCode#488] Zuma Game 祖玛游戏 Think about Zuma Game. You have a row of balls on the table, colored red(R), yellow(Y), blue(B), green(G), and white(W). You also have several balls in your hand. Each time, you may choose a ball in your hand, and insert it into the row (including the leftmost place and rightmost place). Then, if there is a group of 3 or more balls in the same color touching, remove these balls. Keep doing this until no more balls can be removed. Find the minimal balls you have to insert to remove all the balls on the table. If you cannot remove all the balls, output -1. Examples: Input: "WRRBBW", "RB" Output: -1 Explanation: WRRBBW -> WRR[R]BBW -> WBBW -> WBB[B]W -> WW Input: "WWRRBBWW", "WRBRW" Output: 2 Explanation: WWRRBBWW -> WWRR[R]BBWW -> WWBBWW -> WWBB[B]WW -> WWWW -> empty Input:"G", "GGGGG" Output: 2 Explanation: G -> G[G] -> GG[G] -> empty Input: "RBYYBBRRB", "YRBGB" Output: 3 Explanation: RBYYBBRRB -> RBYY[Y]BBRRB -> RBBBRRB -> RRRB -> B -> B[B] -> BB[B] -> empty Note: You may assume that the initial row of balls on the table won't have any 3 or more consecutive balls with the same color. The number of balls on the table won't exceed 20, and the string represents these balls is called "board" in the input. The number of balls in your hand won't exceed 5, and the string represents these balls is called "hand" in the input. Both input strings will be non-empty and only contain characters 'R','Y','B','G','W'.

board,不会有连续三个以上的同色球 #1 递归 看board上各个section的球。尝试用hand上的球去消除这个section,统计是否可行,所用球数 [Mine]对不同的board section用hand上的球解决 #2 递归 看hand上的各个球,尝试插入到board上相同颜色的section上,尝试各种同颜色section,看看是否可以把board消除干净。

[LeetCode#410] Split Array Largest Sum 分割数组的最大值 Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays. Note: Given m satisfies the following constraint: 1 ≤ m ≤ length(nums) ≤ 14,000. Examples: Input: nums = [7,2,5,10,8] m = 2 Output: 18 Explanation: There are four ways to split nums into two subarrays. The best way is to split it into [7,2,5] and [10,8], where the largest sum among the two subarrays is only 18.

# 二分搜索法 如果m和数组nums的个数相等,那么每个数组都是一个子数组,所以返回nums中最大的数字即可,如果m为1,那么整个nums数组就是一个子数组,返回nums所有数字之和,所以对于其他有效的m值,返回的值必定在上面两个值之间,所以我们可以用二分搜索法来做。 接下来要做的是找出,和最大,且小于等于mid的子数组的个数(由于子数组要保证连续,所以简单的贪婪法即可),如果子数组个数小于m,说明mid大了,如果大于m,说明mid小了。这样不断调试mid,找出子数组个数等于m的mid最小值。 [Mine]把"给定划分组数,找最大sum最小"问题,转化成"给定最大sum,找最少划分组数",用逼近给定划分组数的方法,二分调整对最大sum的最小值猜测。 #2 DP 建立一个二维数组dp,其中dp[i][j]表示将数组中前j个数字分成i组所能得到的最小的各个子数组中最大值,初始化为整型最大值。为了能快速的算出子数组之和,我们还是要建立累计和数组 如果前j个数字要分成i组,那么i的范围是[1, j],所以我们要遍历这中间所有的情况,假如中间任意一个位置k,dp[i-1][k]表示数组中前k个数字分成i-1组所能得到的最小的各个子数组中最大值,而sums[j]-sums[k]就是后面的数字之和,我们取二者之间的较大值,然后和dp[i][j]原有值进行对比,更新dp[i][j]为二者之中的较小值,这样k在[1, j]的范围内扫过一遍,dp[i][j]就能更新到最小值,我们最终返回dp[m][n]即可 分割重现关系(Partition Recurrence Relation),用式子表示是T(i, j) = T(i, m) + T(m+1, j) + C。这里的C就是处理合并两个部分的子问题 for (int i = 1; i <= m; ++i) { for (int j = 1; j <= n; ++j) { for (int k = i - 1; k < j; ++k) { int val = max(dp[i - 1][k], sums[j] - sums[k]); dp[i][j] = min(dp[i][j], val); } } } return dp[m][n]; [Mine]最终结果depend on上一次划分,上一次划分是在更短的字符串和更少的划分次数上。 最简单的一次划分是用累加和解决的

[LeetCode#504] Base 7 基数七 Given an integer, return its base 7 string representation. Example 1: Input: 100 Output: "202" Example 2: Input: -7 Output: "-10" Note: The input will be in range of [-1e7, 1e7].

# 迭代 # 递归 string convertToBase7(int num) { if (num < 0) return "-" + convertToBase7(-num); if (num < 7) return to_string(num); return convertToBase7(num / 7) + to_string(num % 7); }

[LeetCode#516] Longest Palindromic Subsequence 最长回文子序列 Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000. Example 1: Input: "bbbab" Output: 4 One possible longest palindromic subsequence is "bbbb". Example 2: Input: "cbbd" Output: 2 One possible longest palindromic subsequence is "bb".

#1 DP dp[i][j] = dp[i + 1][j - 1] + 2 ,if (s[i] == s[j]) dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]),if (s[i] != s[j]) #2 DP,对空间进行优化,只用一个一维的dp数组 #3 DFS+Memory if (s[i] == s[j]) { memo[i][j] = helper(s, i + 1, j - 1, memo) + 2; } else { memo[i][j] = max(helper(s, i + 1, j, memo), helper(s, i, j - 1, memo)); } [Mine]DP是DFS+Memory的迭代写法

[LeetCode#494] Target Sum 目标和 You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symbols + and -. For each integer, you should choose one from + and - as its new symbol. Find out how many ways to assign symbols to make sum of integers equal to target S. Example 1: Input: nums is [1, 1, 1, 1, 1], S is 3. Output: 5 Explanation: -1+1+1+1+1 = 3 +1-1+1+1+1 = 3 +1+1-1+1+1 = 3 +1+1+1-1+1 = 3 +1+1+1+1-1 = 3 There are 5 ways to assign symbols to make the sum of nums be target 3. Note: The length of the given array is positive and will not exceed 20. The sum of elements in the given array will not exceed 1000. Your output answer is guaranteed to be fitted in a 32-bit integer.

#1 DSF 在递归函数中,分别对目标值进行加上当前数字调用递归,和减去当前数字调用递归,这样会涵盖所有情况,并且当所有数字遍历完成后,我们看若目标值为0了,则结果res自增1 #2 DSF + memory [Mine] #2应该最容易想到 #3 DP dp[i][j]表示到第i-1个数字且和为j的情况总数 HashMap<Integer, Integer> dp[n]; sum = dp[i].key, cnt=dp[i].getValue(sum); cnt2 = dp[i+1].getValue(sum +- num[i]) + cnt dp[i+1].put(sum +- num[i], cnt2) return dp[n].getValue(targetSum) #4 DP + 空间优化 只用一个哈希表,而不是用一个数组的哈希表,我们在遍历数组中的每一个数字时,新建一个哈希表,我们在遍历原哈希表中的项时更新这个新建的哈希表,最后把新建的哈希表整个赋值和原哈希表 [Mine]一维哈希表数组降为一个哈希表 #5 DP, 0-1 knapsack (花花酱 LeetCode 494. Target Sum 下 - 刷题找工作 EP157) input scope: -sum(n)~+sum(n); if offset the input: 0~2*sum(n), new target is sum(n)+target; then half input:0~sum(n), new target is (sum(n)+target)/2; now it is 0-1 knapsack

[LeetCode#441] Arranging Coins 排列硬币 You have a total of n coins that you want to form in a staircase shape, where every k-th row must have exactly k coins. Given n, find the total number of full staircase rows that can be formed. n is a non-negative integer and fits within the range of a 32-bit signed integer. Example 1: n = 5 The coins can form the following rows: ¤ ¤ ¤ ¤ ¤ Because the 3rd row is incomplete, we return 2. Example 2: n = 8 The coins can form the following rows: ¤ ¤ ¤ ¤ ¤ ¤ ¤ ¤ Because the 4th row is incomplete, we return 3.

#1 O(n) 从第一行开始,一行一行的从n中减去,如果此时剩余的硬币没法满足下一行需要的硬币数了,我们之间返回当前行数即可 #2 O(lgn) 二分搜索法,我们搜索前i行之和刚好大于n的临界点,这样我们减一个就是能排满的行数 sum_i = (1 + i) * i / 2 #1 O(1) x = (-1 + sqrt(8 * n + 1)) / 2, 然后取整后就是能填满的行数

[LeetCode#418] Sentence Screen Fitting 调整屏幕上的句子 Given a rows x cols screen and a sentence represented by a list of words, find how many times the given sentence can be fitted on the screen. Note: A word cannot be split into two lines. The order of words in the sentence must remain unchanged. Two consecutive words in a line must be separated by a single space. Total words in the sentence won't exceed 100. Length of each word won't exceed 10. 1 ≤ rows, cols ≤ 20,000. Example 1: Input: rows = 2, cols = 8, sentence = ["hello", "world"] Output: 1 Explanation: hello--- world--- The character '-' signifies an empty space on the screen. Example 2: Input: rows = 3, cols = 6, sentence = ["a", "bcd", "e"] Output: 2 Explanation: a-bcd- e-a--- bcd-e- The character '-' signifies an empty space on the screen. Example 3: Input: rows = 4, cols = 5, sentence = ["I", "had", "apple", "pie"] Output: 1 Explanation: I-had apple pie-I had-- The character '-' signifies an empty space on the screen.

#1 [Mine] ?????? #2 需要统计加空格的句子总长度,然后遍历每一行,初始化colsRemaining为cols,然后还需要一个变量idx,来记录当前单词的位置,如果colsRemaining大于0,就进行while循环,如果当前单词的长度小于等于colsRemaining,说明可以放下该单词,那么就减去该单词的长度就是剩余的空间,然后如果此时colsRemaining仍然大于0,则减去空格的长度1,然后idx自增1,如果idx此时超过单词个数的范围了,说明一整句可以放下,那么就有可能出现宽度远大于句子长度的情况,所以我们加上之前放好的一句之外,还要加上colsRemaining/len的个数,然后colsRemaining%len是剩余的位置,此时idx重置为0 [Mine]是否需要某种方法找到循环字段?

[LeetCode#480] Sliding Window Median 滑动窗口中位数 Median is the middle value in an ordered integer list. If the size of the list is even, there is no middle value. So the median is the mean of the two middle value. Examples: [2,3,4] , the median is 3 [2,3], the median is (2 + 3) / 2 = 2.5 Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. Your job is to output the median array for each window in the original array. For example, Given nums = [1,3,-1,-3,5,3,6,7], and k = 3. Window position Median --------------- ----- [1 3 -1] -3 5 3 6 7 1 1 [3 -1 -3] 5 3 6 7 -1 1 3 [-1 -3 5] 3 6 7 -1 1 3 -1 [-3 5 3] 6 7 3 1 3 -1 -3 [5 3 6] 7 5 1 3 -1 -3 5 [3 6 7] 6 Therefore, return the median sliding window as [1,-1,-1,3,5,6]. Note: You may assume k is always valid, ie: 1 ≤ k ≤ input array's size for non-empty array.

#1 multiset #2 similar to #295 Find Median from Data Stream 维护了small和large两个堆,分别保存有序数组的左半段和右半段的数字

[LeetCode#581] Shortest Unsorted Continuous Subarray 最短无序连续子数组 Given an integer array, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order, too. You need to find the shortest such subarray and output its length. Example 1: Input: [2, 6, 4, 8, 10, 9, 15] Output: 5 Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order. Note: Then length of the input array is in range [1, 10,000]. The input array may contain duplicates, so ascending order here means <=.

#1 一个变量start来记录起始位置,然后我们开始遍历数组,当我们发现某个数字比其前面的数字要小的时候,说明此时数组不再有序,所以我们要将此数字向前移动,移到其应该在的地方,我们用另一个变量j来记录移动到的位置,然后我们考虑要不要用这个位置来更新start的值。res=最后一个失序的index到start的距离 [Mine]O(1)的空间复杂度的冒泡排序 #2 新一个跟原数组一摸一样的数组,然后排序。从数组起始位置开始,两个数组相互比较,当对应位置数字不同的时候停止,同理再从末尾开始,对应位置上比较,也是遇到不同的数字时停止,这样中间一段就是最短无序连续子数组了 #3 O(n)的时间复杂度加上O(1)的空间复杂度 int mn = nums[n - 1], mx = nums[0]; for (int i = 1; i < n; ++i) { mx = max(mx, nums[i]); mn = min(mn, nums[n - 1 - i]); if (mx > nums[i]) end = i; if (mn < nums[n - 1 - i]) start = n - 1 - i; } return end - start + 1; [Mine]在升序和降序方向上同时扫描,寻找失序的地方,这里的失序不是和前一个number比,而是和前面所有number的最值比。

[LeetCode#476] Number Complement 补数 Given a positive integer, output its complement number. The complement strategy is to flip the bits of its binary representation. Note: The given integer is guaranteed to fit within the range of a 32-bit signed integer. You could assume no leading zero bit in the integer's binary representation. Example 1: Input: 5 Output: 2 Explanation: The binary representation of 5 is 101 (no leading zero bits), and its complement is 010. So you need to output 2. Example 2: Input: 1 Output: 0 Explanation: The binary representation of 1 is 1 (no leading zero bits), and its complement is 0. So you need to output 0.

#1 从高往低遍历,如果遇到第一个1了后,我们的flag就赋值为true,然后就可以进行翻转了,翻转的方法就是对应位异或一个1即可 #2 只要用一个mask来标记最高位1前面的所有0的位置,然后对mask取反后,与上对num取反的结果即可 int mask = INT_MAX; while (mask & num) mask <<= 1; return ~mask & ~num;

[LeetCode#566] Reshape the Matrix 重塑矩阵 In MATLAB, there is a very useful function called 'reshape', which can reshape a matrix into a new one with different size but keep its original data. You're given a matrix represented by a two-dimensional array, and two positive integers r and c representing the row number and column number of the wanted reshaped matrix, respectively. The reshaped matrix need to be filled with all the elements of the original matrix in the same row-traversing order as they were. If the 'reshape' operation with given parameters is possible and legal, output the new reshaped matrix; Otherwise, output the original matrix. Example 1: Input: nums = [[1,2], [3,4]] r = 1, c = 4 Output: [[1,2,3,4]] Explanation: The row-traversing of nums is [1,2,3,4]. The new reshaped matrix is a 1 * 4 matrix, fill it row by row by using the previous list. Example 2: Input: nums = [[1,2], [3,4]] r = 2, c = 4 Output: [[1,2], [3,4]] Explanation: There is no way to reshape a 2 * 2 matrix to a 2 * 4 matrix. So output the original matrix. Note: The height and width of the given matrix is in range [1, 100]. The given r and c are all positive.

#1 先判断给定数组是否能重塑成给定的大小,就是看两者的元素总数是否相同,直接行数乘以列数即可,然后我们新建一个目标大小的数组,并开始遍历,对于每个位置,我们先转为拉直后的一维坐标,然后在算出在原数组中的对应位置赋值过来即可 int k = i * c + j; res[i][j] = nums[k / n][k % n]; #2 for (int i = 0; i < r * c; ++i) { res[i / c][i % c] = nums[i / n][i % n]; }

[LeetCode#513] Find Bottom Left Tree Value 寻找最左下树结点的值 Given a binary tree, find the leftmost value in the last row of the tree. Example 1: Input: 2 / \ 1 3 Output: 1 Example 2: Input: 1 / \ 2 3 / / \ 4 5 6 / 7 Output: 7 Note: You may assume the tree (i.e., the given root node) is not NULL.

#1 先序遍历遍历的顺序是根-左-右,所以每一行最左边的结点肯定最先遍历到,那么由于是新一行,那么当前深度肯定比之前的最大深度大,所以我们可以更新最大深度为当前深度,结点值res为当前结点值 [Mine]先序遍历,同时记录深度,当深度增长时,当前节点就是当前深度最左节点 #2 层序遍历时遍历完当前行所有结点之后才去下一行,那么我们再遍历每行第一个结点时更新结果res即可,根本不用维护最大深度了

[LeetCode#501] Find Mode in Binary Search Tree 找二分搜索数的众数 Given a binary search tree (BST) with duplicates, find all the mode(s) (the most frequently occurred element) in the given BST. Assume a BST is defined as follows: The left subtree of a node contains only nodes with keys less than or equal to the node's key. The right subtree of a node contains only nodes with keys greater than or equal to the node's key. Both the left and right subtrees must also be binary search trees. For example: Given BST [1,null,2,2], 1 \ 2 / 2 return [2]. Note: If a tree has more than one mode, you can return them in any order. Follow up: Could you do that without using any extra space? (Assume that the implicit stack space incurred due to recursion does not count).

#1 利用一个哈希表来记录数字和其出现次数之前的映射,然后维护一个变量mx来记录当前最多的次数值,这样在遍历完树之后,根据这个mx值就能把对应的元素找出来。那么用这种方法的话就不需要用到二分搜索树的性质了,随意一种遍历方式都可以 #2 由于是二分搜索树,那么我们中序遍历出来的结果就是有序的,这样我们只要比较前后两个元素是否相等,就等统计出现某个元素出现的次数,因为相同的元素肯定是都在一起的

[LeetCode#419] Battleships in a Board 平板上的战船 Given an 2D board, count how many different battleships are in it. The battleships are represented with 'X's, empty slots are represented with '.'s. You may assume the following rules: You receive a valid board, made of only battleships or empty slots. Battleships can only be placed horizontally or vertically. In other words, they can only be made of the shape 1xN (1 row, N columns) or Nx1 (N rows, 1 column), where N can be of any size. At least one horizontal or vertical cell separates between two battleships - there are no adjacent battleships. Example: X..X ...X ...X In the above board there are 2 battleships. Invalid Example: ...X XXXX ...X This is not a valid board - as battleships will always have a cell separating between them. Your algorithm should not modify the value of the board.

#1 只需要遍历一次二维数组就行了,只要找出战舰的起始点。所谓的战舰起始点,就是为X的点,而且该点的上方和左边的点不能为X,所以我们只要找出所有满足这个条件的点即可 #2 DFS or BFS ,既然没有相邻的战舰,那就寻找连续的点就行了

[LeetCode#496] Next Greater Element I 下一个较大的元素之一 You are given two arrays (without duplicates) nums1 and nums2 where nums1's elements are subset of nums2. Find all the next greater numbers for nums1's elements in the corresponding places of nums2. The Next Greater Number of a number x in nums1 is the first greater number to its right in nums2. If it does not exist, output -1 for this number. Example 1: Input: nums1 = [4,1,2], nums2 = [1,3,4,2]. Output: [-1,3,-1] Explanation: For number 4 in the first array, you cannot find the next greater number for it in the second array, so output -1. For number 1 in the first array, the next greater number for it in the second array is 3. For number 2 in the first array, there is no next greater number for it in the second array, so output -1. Example 2: Input: nums1 = [2,4], nums2 = [1,2,3,4]. Output: [3,-1] Explanation: For number 2 in the first array, the next greater number for it in the second array is 3. For number 4 in the first array, there is no next greater number for it in the second array, so output -1. Note: All elements in nums1 and nums2 are unique. The length of both nums1 and nums2 would not exceed 1000.

#1 哈希表先来建立每个数字和其坐标位置之间的映射,那么我们在遍历子集合中的数字时,就能直接定位到该数字在原数组中的位置,然后再往右边遍历寻找较大数即可 #2 哈希表和栈 从前到后遍历原数组中的所有数字,如果此时栈不为空,且栈顶元素小于当前数字,说明当前数字就是栈顶元素的右边第一个较大数,那么建立二者的映射,并且去除当前栈顶元素,最后将当前遍历到的数字压入栈

[LeetCode#454] 4Sum II 四数之和之二 Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l) there are such that A[i] + B[j] + C[k] + D[l] is zero. To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1. Example: Input: A = [ 1, 2] B = [-2,-1] C = [-1, 2] D = [ 0, 2] Output: 2 Explanation: The two tuples are: 1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0 2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0

#1 如果把A和B的两两之和都求出来,在哈希表中建立两数之和跟其出现次数之间的映射,那么我们再遍历C和D中任意两个数之和,我们只要看哈希表存不存在这两数之和的相反数就行了 #2 两个哈希表分别记录AB和CD的两两之和出现次数,然后遍历其中一个哈希表,并在另一个哈希表中找和的相反数出现的次数 for (auto a : m1) res += a.second * m2[-a.first];

[LeetCode#529] Minesweeper 扫雷游戏 Let's play the minesweeper game (Wikipedia, online game)! You are given a 2D char matrix representing the game board. 'M' represents an unrevealed mine, 'E' represents an unrevealed empty square, 'B' represents a revealed blank square that has no adjacent (above, below, left, right, and all 4 diagonals) mines, digit ('1' to '8') represents how many mines are adjacent to this revealed square, and finally 'X' represents a revealed mine. Now given the next click position (row and column indices) among all the unrevealed squares ('M' or 'E'), return the board after revealing this position according to the following rules: If a mine ('M') is revealed, then the game is over - change it to 'X'. If an empty square ('E') with no adjacent mines is revealed, then change it to revealed blank ('B') and all of its adjacent unrevealed squares should be revealed recursively. If an empty square ('E') with at least one adjacent mine is revealed, then change it to a digit ('1' to '8') representing the number of adjacent mines. Return the board when no more squares will be revealed. Example 1: Input: [['E', 'E', 'E', 'E', 'E'], ['E', 'E', 'M', 'E', 'E'], ['E', 'E', 'E', 'E', 'E'], ['E', 'E', 'E', 'E', 'E']] Click : [3,0] Output: [['B', '1', 'E', '1', 'B'], ['B', '1', 'M', '1', 'B'], ['B', '1', '1', '1', 'B'], ['B', 'B', 'B', 'B', 'B']] Explanation: Example 2: Input: [['B', '1', 'E', '1', 'B'], ['B', '1', 'M', '1', 'B'], ['B', '1', '1', '1', 'B'], ['B', 'B', 'B', 'B', 'B']] Click : [1,2] Output: [['B', '1', 'E', '1', 'B'], ['B', '1', 'X', '1', 'B'], ['B', '1', '1', '1', 'B'], ['B', 'B', 'B', 'B', 'B']] Explanation: Note: The range of the input matrix's height and width is [1,50]. The click position will only be an unrevealed square ('M' or 'E'), which also means the input board contains at least one clickable square. The input board won't be a stage when game is over (some mines have been revealed). For simplicity, not mentioned rules should be ignored in this problem. For example, you don't need to reveal all the unrevealed mines when the game is over, consider any cases that you will win the game or flag any squares.

#1 对于当前需要点击的点,我们先判断是不是雷,是的话直接标记X返回即可。如果不是的话,我们就数该点周围的雷个数,如果周围有雷,则当前点变为雷的个数并返回。如果没有的话,我们再对周围所有的点调用递归函数再点击即可 #2 根据第一次找周围雷个数的时候,若此时cnt个数为0并且标识是E的位置记录下来,那么如果最后雷个数确实为0了的话,我们直接遍历我们保存下来为E的位置调用递归函数即可,就不用再写两个for循环了 #3 BFS + queue

[LeetCode#515] Find Largest Value in Each Tree Row 找树每行最大的结点值 You need to find the largest value in each row of a binary tree. Example: Input: 1 / \ 3 2 / \ \ 5 3 9 Output: [1, 3, 9]

#1 层序遍历,然后在每一层中找到最大值,加入结果res中即可 #2 先序遍历,这样的话就需要维护一个深度变量depth,来记录当前结点的深度,如果当前深度大于结果res的长度,说明这个新一层,我们将当前结点值加入结果res中,如果不大于res的长度的话,我们用当前结点值和结果res中对应深度的那个结点值相比较,取较大值赋给结果res中的对应深度位置

[LeetCode#461] Hamming Distance 汉明距离 The Hamming distance between two integers is the number of positions at which the corresponding bits are different. Given two integers x and y, calculate the Hamming distance. Note: 0 ≤ x, y < 231. Example: Input: x = 1, y = 4 Output: 2 Explanation: 1 (0 0 0 1) 4 (0 1 0 0) ↑ ↑ The above arrows point to positions where the corresponding bits are different.

#1 按位分别取出两个数对应位上的数并异或 #2 直接将两个数字异或起来,然后我们遍历异或结果的每一位,统计为1的个数 #3 num & (num - 1)可以快速地移除最右边的bit 1, 一直循环到num为0, 总的循环数就是num中bit 1的个数

[LeetCode#405] Convert a Number to Hexadecimal 数字转为十六进制 Given an integer, write an algorithm to convert it to hexadecimal. For negative integer, two's complement method is used. Note: All letters in hexadecimal (a-f) must be in lowercase. The hexadecimal string must not contain extra leading 0s. If the number is zero, it is represented by a single zero character '0'; otherwise, the first character in the hexadecimal string will not be the zero character. The given number is guaranteed to fit within the range of a 32-bit signed integer. You must not use any method provided by the library which converts/formats the number to hex directly. Example 1: Input: 26 Output: "1a" Example 2: Input: -1 Output: "ffffffff"

#1 数字范围就是0到UINT_MAX,即为16^8-1,那么最高位就是16^7,我们首先除以这个数字,如果商大于等于10,我们用字母代替,否则就是用数字代替,然后对其余数进行同样的处理,一直到当前数字为0停止,最后我们还要补齐末尾的0 #2 位操作的思路,每次取出最右边四位,如果其大于等于10,找到对应的字母加入结果,反之则将对应的数字加入结果,然后num像右平移四位,循环停止的条件是num为0,或者是已经循环了7次

[LeetCode#503] Next Greater Element II 下一个较大的元素之二 Given a circular array (the next element of the last element is the first element of the array), print the Next Greater Number for every element. The Next Greater Number of a number x is the first greater number to its traversing-order next in the array, which means you could search circularly to find its next greater number. If it doesn't exist, output -1 for this number. Example 1: Input: [1,2,1] Output: [2,-1,2] Explanation: The first 1's next greater number is 2; The number 2 can't find next greater number; The second 1's next greater number needs to search circularly, which is also 2. Note: The length of given array won't exceed 10000.

#1 暴力搜索 O(N^2) #2 栈 O(N) 我们遍历两倍的数组,然后还是坐标i对n取余,取出数字,如果此时栈不为空,且栈顶元素小于当前数字,说明当前数字就是栈顶元素的右边第一个较大数,那么建立二者的映射,并且去除当前栈顶元素,最后如果i小于n,则把i压入栈。因为res的长度必须是n,超过n的部分我们只是为了给之前栈中的数字找较大值,所以不能压入栈, [Mine]从前向后遍历,栈里只保存当前数之前,比它大的数,因为小的数都以当前数为答案,出栈了

[LeetCode#535] Encode and Decode TinyURL 编码和解码精简URL地址 Note: This is a companion problem to the System Design problem: Design TinyURL. TinyURL is a URL shortening service where you enter a URL such as https://leetcode.com/problems/design-tinyurl and it returns a short URL such as http://tinyurl.com/4e9iAk. Design the encode and decode methods for the TinyURL service. There is no restriction on how your encode/decode algorithm should work. You just need to ensure that a URL can be encoded to a tiny URL and the tiny URL can be decoded to the original URL.

#1 最简单的一种编码就是用个计数器,当前是第几个存入的url就编码成几,然后解码的时候也能根据数字来找到原来的url, #2 用哈希表建立6位字符和url之间的映射,如果随机生成的字符之前已经存在了,我们就继续随机生成新的字符串,直到生成了之前没有的字符串为止。

[LeetCode#445] Add Two Numbers II 两个数字相加之二 You are given two linked lists representing two non-negative numbers. The most significant digit comes first and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. You may assume the two numbers do not contain any leading zero, except the number 0 itself. Follow up: What if you cannot modify the input lists? In other words, reversing the lists is not allowed. Example: Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 8 -> 0 -> 7

#1 栈 #2 递归 #3 由左到右,不断寻找要计算的位和可能被进位的位

[LeetCode#481] Magical String 神奇字符串 A magical string S consists of only '1' and '2' and obeys the following rules: The string S is magical because concatenating the number of contiguous occurrences of characters '1' and '2' generates the string S itself. The first few elements of string S is the following: S = "1221121221221121122......" If we group the consecutive '1's and '2's in S, it will be: 1 22 11 2 1 22 1 22 11 2 11 22 ...... and the occurrences of '1's or '2's in each group are: 1 2 2 1 1 2 1 2 2 1 2 2 ...... You can see that the occurrence sequence above is the S itself. Given an integer N as input, return the number of '1's in the first N number in the magical string S. Note: N will not exceed 100,000. Example 1: Input: 6 Output: 3 Explanation: The first 6 elements of magical string S is "12211" and it contains three 1's, so return 3.

#1 根据第三个数字2开始往后生成数字,此时生成两个1,然后根据第四个数字1,生成一个2,再根据第五个数字1,生成一个1,以此类推,生成的数字1或2可能通过异或3来交替生成,在生成的过程中同时统计1的个数即可 #2 string s = "122"; int i = 2; while (s.size() < n) { s += string(s[i++] - '0', s.back() ^ 3); } return count(s.begin(), s.begin() + n, '1');

[LeetCode#403] Frog Jump 青蛙过河 A frog is crossing a river. The river is divided into x units and at each unit there may or may not exist a stone. The frog can jump on a stone, but it must not jump into the water. Given a list of stones' positions (in units) in sorted ascending order, determine if the frog is able to cross the river by landing on the last stone. Initially, the frog is on the first stone and assume the first jump must be 1 unit. If the frog's last jump was k units, then its next jump must be either k - 1, k, or k + 1 units. Note that the frog can only jump in the forward direction. Note: The number of stones is ≥ 2 and is < 1,100. Each stone's position will be a non-negative integer < 231. The first stone's position is always 0. Example 1: [0,1,3,5,6,8,12,17] There are a total of 8 stones. The first stone at the 0th unit, second stone at the 1st unit, third stone at the 3rd unit, and so on... The last stone at the 17th unit. Return true. The frog can jump to the last stone by jumping 1 unit to the 2nd stone, then 2 units to the 3rd stone, then 2 units to the 4th stone, then 3 units to the 6th stone, 4 units to the 7th stone, and 5 units to the 8th stone. Example 2: [0,1,2,3,4,8,9,11] Return false. There is no way to jump to the last stone as the gap between the 5th and 6th stone is too large.

#1 递归 以位置和跳跃能力为key(key = pos | jump << 11),遍历每个位置可能得到测跳跃能力。 [Mine]对可能跳到的石头和跳跃力进行递归推进,如果最终可以到对岸,递归返回true,中间任何其他情况,要么skip,要么返回false 用一个哈希表来建立每个石头和在该位置上能获得的弹跳力集合(与起跳点的距离)之间的映射,并且建立一个一维maxJump数组,maxJump[i]表示在位置为i的石头青蛙的最大弹跳力(只有青蛙能跳到该石头上,maxJump[i]才大于0) [Mine]k是起跳石,i是目标石,计算从起跳石到目标石之间所有石头,可以跳到目标石时的弹跳力。计算后i++,如果目标石超过起跳石的最大弹跳力范围,k++ 这样k是可以直接跳到目标石的下限,不用每次都从头计算。 [Mine]maxJump数组并不是为了DP,它是为了减少Iterative 回溯。 [Mine]由于"either k - 1, k, or k + 1 units"限制,每次最大弹跳力不一定是最佳方案,所以需要记录每个位置可能得到的跳跃能力 [Mine]感觉递归+Meno更容易想到

[LeetCode#572] Subtree of Another Tree 另一个树的子树 Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node's descendants. The tree scould also be considered as a subtree of itself. Example 1: Given tree s: 3 / \ 4 5 / \ 1 2 Given tree t: 4 / \ 1 2 Return true, because t has the same structure and node values with a subtree of s. Example 2: Given tree s: 3 / \ 4 5 / \ 1 2 / 0 Given tree t: 4 / \ 1 2 Return false.

#1 递归 先从s的根结点开始,跟t比较,如果两棵树完全相同,那么返回true,否则就分别对s的左子结点和右子结点调用递归再次来判断是否相同,只要有一个返回true了,就表示可以找得到 #2 序列化,字符串比较 序列化的时候要特殊处理一下,就是在每个结点值前面都加上一个字符,比如',',来分隔开

[LeetCode#485] Max Consecutive Ones 最大连续1的个数 Given a binary array, find the maximum number of consecutive 1s in this array. Example 1: Input: [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. Note: The input array will only contain 0 and 1. The length of input array is a positive integer and will not exceed 10,000

#1 遍历一遍数组,用一个计数器cnt来统计1的个数,方法是如果当前数字为0,那么cnt重置为0,如果不是0,cnt自增1,然后每次更新结果res即可

[LeetCode#438] Find All Anagrams in a String 找出字符串中所有的变位词 Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100. The order of output does not matter. Example 1: Input: s: "cbaebabacd" p: "abc" Output: [0, 6] Explanation: The substring with start index = 0 is "cba", which is an anagram of "abc". The substring with start index = 6 is "bac", which is an anagram of "abc". Example 2: Input: s: "abab" p: "ab" Output: [0, 1, 2] Explanation: The substring with start index = 0 is "ab", which is an anagram of "ab". The substring with start index = 1 is "ba", which is an anagram of "ab". The substring with start index = 2 is "ab", which is an anagram of "ab".

#1 首先就要统计字符串p中字符出现的次数,然后从s的开头开始,每次找p字符串长度个字符,来验证字符个数是否相同,如果不相同出现了直接break,如果一直都相同了,则将起始位置加入结果res中 #2 用两个哈希表,分别记录p的字符个数,和s中前p字符串长度的字符个数,然后比较,如果两者相同,则将0加入结果res中,然后开始遍历s中剩余的字符,每次右边加入一个新的字符,然后去掉左边的一个旧的字符,每次再比较两个哈希表是否相同即可 #3 滑动窗口Sliding Window,与#2差不多,只是不每次对比hashmap,而是用一个变量记录和p的hashmap的差距。

[LeetCode#456] 132 Pattern 132模式 Given a sequence of n integers a1, a2, ..., an, a 132 pattern is a subsequence ai, aj, ak such that i < j < k and ai < ak < aj. Design an algorithm that takes a list of n numbers as input and checks whether there is a 132 pattern in the list. Note: n will be less than 15,000. Example 1: Input: [1, 2, 3, 4] Output: False Explanation: There is no 132 pattern in the sequence. Example 2: Input: [3, 1, 4, 2] Output: True Explanation: There is a 132 pattern in the sequence: [1, 4, 2]. Example 3: Input: [-1, 3, 2, 0] Output: True Explanation: There are three 132 patterns in the sequence: [-1, 3, 2], [-1, 3, 0] and [-1, 2, 0].

#1 首先我们来找第一个数,这个数需要最小,那么我们如果发现当前数字大于等于后面一个数字,我们就往下继续遍历,直到当前数字小于下一个数字停止。然后我们找第二个数字,这个数字需要最大,那么如果我们发现当前数字小于等于下一个数字就继续遍历,直到当前数字大于下一个数字停止。最后就找第三个数字,我们验证这个数字是否在之前两个数字的中间,如果没有找到,我们就从第二个数字的后面一个位置继续开始重新找这三个数字 [Mine]从左向右,找到first<second之后,找是否有third符合first<third<second,如果没有,就试试下一个first<second #2 类似#84 Largest Rectangle in Histogram (Hard)中栈的应用。 *从右向左*, 寻找 second>third,second和third越大越好,越大越容易找到first,为此记录第一对second>third之后,遇到比second更大的,就third=second, second=new, 然后一旦出现了first < third,就可以返回true

[LeetCode#411] Minimum Unique Word Abbreviation 最短的独一无二的单词缩写 A string such as "word" contains the following abbreviations: ["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"] Given a target string and a set of strings in a dictionary, find an abbreviation of this target string with thesmallest possible length such that it does not conflict with abbreviations of the strings in the dictionary. Each number or letter in the abbreviation is considered length = 1. For example, the abbreviation "a32bc" has length = 4. Note: In the case of multiple answers as shown in the second example below, you may return any one of them. Assume length of target string = m, and dictionary size = n. You may assume that m ≤ 21, n ≤ 1000, and log2(n) + m ≤ 20. Examples: "apple", ["blade"] -> "a4" (because "5" or "4e" conflicts with "blade") "apple", ["plain", "amber", "blade"] -> "1p3" (other valid answers include "ap3", "a3e", "2p2", "3le", "3l1").

#1 首先找出target的所有的单词缩写的形式,然后按照长度来排序,小的排前面,我们用优先队列来自动排序,里面存一个pair,保存单词缩写及其长度,然后我们从最短的单词缩写开始,跟dictionary中所有的单词一一进行验证,看其是否是合法的单词的缩写,如果是,说明有冲突,直接break,进行下一个单词缩写的验证 #2 将单词缩写的冲突检测用位运算实现。 字典中的词和target,逐字母比对,相同为1,不同为0,生成二进制比对mask。 单词缩写abbr通过如下原则转化为二进制数字: 缩写中的字母替换为二进制1,数字覆盖的位数替换为二进制0 target缩写二进制和二进制比对mask相与, if NOT target_abbr & conflict_mask == target_abbr,这个缩写符合条件。 #2 Refer to http://bookshadow.com/weblog/2016/10/02/leetcode-minimum-unique-word-abbreviation/

[LeetCode#413] Arithmetic Slices 算数切片 A sequence of number is called arithmetic if it consists of at least three elements and if the difference between any two consecutive elements is the same. For example, these are arithmetic sequence: 1, 3, 5, 7, 9 7, 7, 7, 7 3, -1, -5, -9 The following sequence is not arithmetic. 1, 1, 2, 5, 7 A zero-indexed array A consisting of N numbers is given. A slice of that array is any pair of integers (P, Q) such that 0 <= P < Q < N. A slice (P, Q) of array A is called arithmetic if the sequence: A[P], A[p + 1], ..., A[Q - 1], A[Q] is arithmetic. In particular, this means that P + 1 < Q. The function should return the number of arithmetic slices in the array A. Example: A = [1, 2, 3, 4] return: 3, for 3 arithmetic slices in A: [1, 2, 3], [2, 3, 4] and [1, 2, 3, 4] itself.

Arithmetic是等差数列,限定了等差数列的长度至少为3。 [Mine]一个数列中可能有多个不同的等差数列,这里要找所有大于3的等差数列的切片数之和 定义一个一维dp数组,其中dp[i]表示,到i位置为止的算数切片的个数,那么我们从第三个数字开始遍历,如果当前数字和之前两个数字构成算数切片,那么我们更新dp[i]为dp[i-1]+1,然后res累加上dp[i]的值 可以用一个变量替代DP数组 [Mine]DP[i]是到i位置为止的切片个数,之前到i-1的切片都可以直接算到i中,成为长度大于3的切片,然后加上唯一一个长度等于3的切片:i-2, i-1, i。这就是dp[i]=dp[i-1]+1 [Mine]感觉有问题啊,只计算了,(123),(234),没有算(1234)?????

[LeetCode#433] Minimum Genetic Mutation 最小基因变化 A gene string can be represented by an 8-character long string, with choices from "A", "C", "G", "T". Suppose we need to investigate about a mutation (mutation from "start" to "end"), where ONE mutation is defined as ONE single character changed in the gene string. For example, "AACCGGTT" -> "AACCGGTA" is 1 mutation. Also, there is a given gene "bank", which records all the valid gene mutations. A gene must be in the bank to make it a valid gene string. Now, given 3 things - start, end, bank, your task is to determine what is the minimum number of mutations needed to mutate from "start" to "end". If there is no such a mutation, return -1. Note: Starting point is assumed to be valid, so it might not be included in the bank. If multiple mutations are needed, all mutations during in the sequence must be valid. You may assume start and end string is not the same. Example 1: start: "AACCGGTT" end: "AACCGGTA" bank: ["AACCGGTA"] return: 1 Example 2: start: "AACCGGTT" end: "AAACGGTA" bank: ["AACCGGTA", "AACCGCTA", "AAACGGTA"] return: 2 Example 3: start: "AAAAACCC" end: "AACCCCCC" bank: ["AAAACCCC", "AAACCCCC", "AACCCCCC"] return: 3

BFS 计算距离场,或者每次转变一个字符,BFS 而是对于每个字符,我们都尝试将其换为一个新的字符,每次只换一个,这样会得到一个新的字符串,如果这个字符串在bank中存在,说明这样变换是合法的,加入visited集合和queue中等待下一次遍历,记得在下次置换字符的时候要将之前的还原。我们在queue中取字符串出来遍历的时候,先检测其是否和end相等,相等的话返回level,

[LeetCode#446] Arithmetic Slices II - Subsequence 算数切片之二 - 子序列 A sequence of numbers is called arithmetic if it consists of at least three elements and if the difference between any two consecutive elements is the same. For example, these are arithmetic sequences: 1, 3, 5, 7, 9 7, 7, 7, 7 3, -1, -5, -9 The following sequence is not arithmetic. 1, 1, 2, 5, 7 A zero-indexed array A consisting of N numbers is given. A subsequence slice of that array is any sequence of integers (P0, P1, ..., Pk) such that 0 ≤ P0 < P1 < ... < Pk < N. A subsequence slice (P0, P1, ..., Pk) of array A is called arithmetic if the sequence A[P0], A[P1], ..., A[Pk-1], A[Pk] is arithmetic. In particular, this means that k ≥ 2. The function should return the number of arithmetic subsequence slices in the array A. The input contains N integers. Every integer is in the range of -231 and 231-1 and 0 ≤ N ≤ 1000. The output is guaranteed to be less than 231-1. Example: Input: [2, 4, 6, 8, 10] Output: 7 Explanation: All arithmetic subsequence slices are: [2,4,6] [4,6,8] [6,8,10] [2,4,6,8] [4,6,8,10] [2,4,6,8,10] [2,6,10]

DP 一维数组dp,数组里的元素不是数字,而是放一个哈希表,建立等差数列的差值和其长度之间的映射。 2 4 6 8 10 2->1 4->1 6->1 8->1 2->2 4->1 6->1 2->3 4->2 2->4 [Mine]dp[i],以i与之前每个元素的差值为Key,value是用此差值已经组成的等差数列长度(可以是1)。计算所有i与之前元素j两两相差,如果j的dp有相同差值,那么就可以组成至少长度为3的等差数列 dp[i][diff]=dp[j][diff] + 1,其组合数为dp[j][diff]

[LeetCode#460] LFU Cache 最近最不常用页面置换缓存器 Design and implement a data structure for Least Frequently Used (LFU) cache. It should support the following operations: get and put. get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1. put(key, value) - Set or insert the value if the key is not already present. When the cache reaches its capacity, it should invalidate the least frequently used item before inserting a new item. For the purpose of this problem, when there is a tie (i.e., two or more keys that have the same frequency), the least recently used key would be evicted. Follow up: Could you do both operations in O(1) time complexity? Example: LFUCache cache = new LFUCache( 2 /* capacity */ ); cache.put(1, 1); cache.put(2, 2); cache.get(1); // returns 1 cache.put(3, 3); // evicts key 2 cache.get(2); // returns -1 (not found) cache.get(3); // returns 3. cache.put(4, 4); // evicts key 1. cache.get(1); // returns -1 (not found) cache.get(3); // returns 3 cache.get(4); // returns 4

LRU(Least Recnetly Used)算法是首先淘汰最长时间未被使用的页面, 而LFU(Least Frequently Used)是先淘汰一定时间内被访问次数最少的页面 hash#1 哈希表m来记录当前数据{key, value}和其出现次数之间的映射 hash#2 哈希表freq来建立频率和一个里面所有key都是当前频率的list之间的映射 hash#3 为了快速的定位freq中key的位置,我们再用一个哈希表iter来建立key和freq中key的位置之间的映射 [Mine]m是用来O(1)检测key是否在,更新和获取value的 freq是用来在O(1)找到记录的minfreq的所有key中删除一个 iter是用来在O(1)中增加访问次数时,更新freq用。 [Mine]注意list<int>::iterator>的使用,双向链表

[LeetCode#458] Poor Pigs 可怜的猪 There are 1000 buckets, one and only one of them contains poison, the rest are filled with water. They all look the same. If a pig drinks that poison it will die within 15 minutes. What is the minimum amount of pigs you need to figure out which bucket contains the poison within one hour. Answer this question, and write an algorithm for the follow-up general case. Follow-up: If there are n buckets and a pig drinking poison will die within m minutes, how many pigs (x) you need to figure out the "poison" bucket within p minutes? There is exact one bucket with poison.

[Mine]一头猪一次是一维两列 (判断两个桶) 两头猪一次是两维两列(判断四个桶) 三头猪一次是三维两列(判断八个桶) 一头猪两次是一维三列(判断三个桶) 两头猪两次是两维三列(判断九个桶) 三头猪两次是三维三列(判断二十七个桶) [Mine]理解一,用进制理解维度,进制位数=猪数,进制数=每一位能表示的数=次数+1=p/m + 1: 一次时,每个猪相当于二进制中的一位,所以桶数是2的指数倍(指数为猪的数量);两次时,每个猪相当于三进制的一位(每个猪通过两次可以准确表示0,1,2三个数),所以是3的指数倍。 每次每头猪同时喝的桶数是保持本位固定值,其他位的排列组合数量,即,每位可能取值^(位数-1)=(p/m+1)^(x-1) 理解二:多维扫描:维度=猪数,正多维体边长=次数+1=p/m + 1 一头猪时,每增加一次,能判断的桶数为p/m + 1 多头猪时,每个猪是正多维体的一个维度,正多维体边长是p/m + 1,通过多维交叉印证,正多维体中每一个点由每个维度上的一次实验结果表示 一次实验,一头猪要同时喝很多桶。每次每头猪同时喝的桶数是保持本维度坐标不变,在降维投影上覆盖的点数。比如三头猪,三维正立方体,x维度,第一次,就是[0, 0<=y<=p/m + 1, 0<=z<=p/m + 1]二维平面上的点。 这道题让我们求最少用多少猪来测,那么就是求数组的维度,我们知道了数组的总个数,所以要尽量增加数组的每维的长度,尽量减少维度。这里,数组的每维的长度其实都是测试的次数+1,所以我们首先要确定能测的次数,通过总测试时间除以毒发时间,再加上1就是测试次数。有了数组每维的长度(p/m+1),那么如果有x只猪,能测的桶数为(p/m+1)的x次方,现在我们给定了桶数N,要求x,就log一下就行 (p/m+1)^x=N, x=logN/log(p/m+1) [Mine] 如果a^x=N(a>0,且a≠1),则x叫做以a为底N的对数,记做x=log(a)(N),其中a要写于log右下。其中a叫做对数的底,N叫做真数。通常我们将以10为底的对数叫做常用对数,以e为底的对数称为自然对数。

[LeetCode#493] Reverse Pairs 翻转对 Given an array nums, we call (i, j) an important reverse pair if i < j and nums[i] > 2*nums[j]. You need to return the number of important reverse pairs in the given array. Example1: Input: [1,3,2,3,1] Output: 2 Example2: Input: [2,4,3,5,1] Output: 3 Note: The length of the given array will not exceed 50,000. All the numbers in the input array are in the range of 32-bit integer.

[Mine]最直接的方式就是对每个i,在其后无序数组用nums[i] /2分区,统计小于nums[i] /2的个数。所以是O(N^2)。 OR,逐一插入排序。 #1 顺序重现关系(Sequential Recurrence Relation),用式子表示是T(i, j) = T(i, j - 1) + C。这里的C就是处理最后一个数字的子问题,那么用文字来描述就是"已知翻转对的第二个数字为nums[j], 在子数组nums[i, j - 1]中找翻转对的第一个数字" 从后向前扫描,由于我们要在之前遍历过的数字中找符合条件的数字,怎么样利用BIT的特性来快速的找到是这种解法的最大难点。 树状数组Binary Indexed Tree(BIT) 要存的是该数字在有序数组中的位置,而且存入的也不是该数字本身,而是该数字出现的次数 [Mine]index是有序数组中小于等于此数字的数字个数和,即此数字在有序数组中其最后出现的位置。 [Mine]先将数组排成有序数组 在从后向前扫描,即遍历i找j的过程中,BIT的value是扫描过数字出现的次数。 用lower_bound在有序数组中确定符合nums[i] > 2*nums[j]的j最后出现的位置 这就是BIT的index,用BIT算出当前符合条件的<=j的数字出现次数总和。 sort: O(nlgn) + seek i: O(n) * (BIT update O(lgn) + BIT getSum O(lgn)) = O(nlogn) #2 分割重现关系(Partition Recurrence Relation),用式子表示是T(i, j) = T(i, m) + T(m+1, j) + C。这里的C就是处理合并两个部分的子问题,那么用文字来描述就是"已知翻转对的两个数字分别在子数组nums[i, m]和nums[m+1, j]之中,求满足要求的翻转对的个数" 如果两个子数组是有序的,那么我们可以用双指针的方法在线性时间内就可以统计出符合题意的翻转对的个数 在MergeSort的递归函数中,对于有序的两个子数组进行统计翻转对的个数,然后再逐层返回,这就完美的实现了上述的分割重现关系的思想。 MergeSort (Recursive) O(lgN) * Left/Right Pointer O(n) = O(nlgN) [Mine]T(i, j) = T(i, m) + T(m+1, j) + C,大区间解是小区间解之和,再加上跨区间解。在两个有序子数组中,只扫描一遍i in [i,m] and j in [m+1,j] 即可找到所有符合题意的跨区间解。 [Mine]从后向前遍历,维护一个有序数组,利用二分搜索来找符合题意的对数。这样查找时,确实是O(logN),但插入有序数组时就是O(N)了,这样整体就是O(N^2) #1 不做插入,利用BIT只做O(logN)的查找和O(logN)的getsum+update #2 不做整体遍历,整体O(NlogN)的mergeSort中,将两个有序子数组中找pair的过程平行放在了O(N)的merge中

[LeetCode#412] Fizz Buzz 嘶嘶嗡嗡 Write a program that outputs the string representation of numbers from 1 to n. But for multiples of three it should output "Fizz" instead of the number and for the multiples of five output "Buzz". For numbers which are multiples of both three and five output "FizzBuzz". Example: n = 15, Return: [ "1", "2", "Fizz", "4", "Buzz", "Fizz", "7", "8", "Fizz", "Buzz", "11", "Fizz", "13", "14", "FizzBuzz" ]

for (int i = 1; i <= n; ++i) { if (i % 15 == 0) res.push_back("FizzBuzz"); else if (i % 3 == 0) res.push_back("Fizz"); else if (i % 5 == 0) res.push_back("Buzz"); else res.push_back(to_string(i)); }

[LeetCode#449] Serialize and Deserialize BST 二叉搜索树的序列化和去序列化 Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment. Design an algorithm to serialize and deserialize a binary search tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary search tree can be serialized to a string and this string can be deserialized to the original tree structure. The encoded string should be as compact as possible. Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.

same to #297 没发现跟之前那题有何不同,而且也没有看到能够利用BST性质的方法 #1 递归,先续遍历 #2 非递归,层序遍历 如果利用BST的性质的话, 是不需要特殊符号来表示空节点的 [Mine]先序存入;去序列化时,每取出一个数字,更新其左右支的取值范围,递归建造左右支。

[LeetCode#568] Maximum Vacation Days 最大化休假日 LeetCode wants to give one of its best employees the option to travel among N cities to collect algorithm problems. But all work and no play makes Jack a dull boy, you could take vacations in some particular cities and weeks. Your job is to schedule the traveling to maximize the number of vacation days you could take, but there are certain rules and restrictions you need to follow. Rules and restrictions: You can only travel among N cities, represented by indexes from 0 to N-1. Initially, you are in the city indexed 0 on Monday. The cities are connected by flights. The flights are represented as a N*N matrix (not necessary symmetrical), called flights representing the airline status from the city i to the city j. If there is no flight from the city i to the city j, flights[i][j] = 0; Otherwise, flights[i][j] = 1. Also, flights[i][i] = 0 for all i. You totally have K weeks (each week has 7 days) to travel. You can only take flights at most once per day and can only take flights on each week's Monday morning. Since flight time is so short, we don't consider the impact of flight time. For each city, you can only have restricted vacation days in different weeks, given an N*K matrix called days representing this relationship. For the value of days[i][j], it represents the maximum days you could take vacation in the city i in the week j. You're given the flights matrix and days matrix, and you need to output the maximum vacation days you could take during K weeks. Example 1: Input:flights = [[0,1,1],[1,0,1],[1,1,0]], days = [[1,3,1],[6,0,3],[3,3,3]] Output: 12 Explanation: Ans = 6 + 3 + 3 = 12. One of the best strategies is: 1st week : fly from city 0 to city 1 on Monday, and play 6 days and work 1 day. (Although you start at city 0, we could also fly to and start at other cities since it is Monday.) 2nd week : fly from city 1 to city 2 on Monday, and play 3 days and work 4 days. 3rd week : stay at city 2, and play 3 days and work 4 days. Example 2: Input:flights = [[0,0,0],[0,0,0],[0,0,0]], days = [[1,1,1],[7,7,7],[7,7,7]] Output: 3 Explanation: Ans = 1 + 1 + 1 = 3. Since there is no flights enable you to move to another city, you have to stay at city 0 for the whole 3 weeks. For each week, you only have one day to play and six days to work. So the maximum number of vacation days is 3. Example 3: Input:flights = [[0,1,1],[1,0,1],[1,1,0]], days = [[7,0,0],[0,7,0],[0,0,7]] Output: 21 Explanation: Ans = 7 + 7 + 7 = 21 One of the best strategies is: 1st week : stay at city 0, and play 7 days. 2nd week : fly from city 0 to city 1 on Monday, and play 7 days. 3rd week : fly from city 1 to city 2 on Monday, and play 7 days. Note: N and K are positive integers, which are in the range of [1, 100]. In the matrix flights, all the values are integers in the range of [0, 1]. In the matrix days, all the values are integers in the range [0, 7]. You could stay at a city beyond the number of vacation days, but you should work on the extra days, which won't be counted as vacation days. If you fly from the city A to the city B and take the vacation on that day, the deduction towards vacation days will count towards the vacation days of city B in that week. We don't consider the impact of flight hours towards the calculation of vacation days.

一个NxN的数组,表示城市i是否有飞机直达城市j,又给了我们一个NxK的数组days,表示在第j周能在城市i休假的天数,让我们找出一个行程能使我们休假的天数最大化 #1 DP 二维DP数组,其中dp[i][j]表示目前是第j周,并且在此时在城市i,总共已经获得休假的总日子数。 dp[i][j]表示的是当前是第j周并在城市i已经获得的休假总日子数,那么上一个状态,也就是j+1周(因为我们是从后往前更新),跟当前状态有何联系,上一周我们可能还在城市i,也可能在其他城市p,那么在其他城市p的条件是,城市p有直飞城市i的飞机,那么我们可以用上一个状态的值dp[p][j+1]来更新当前值dp[i][j],还要注意的是我们要从倒数第二周开始更新,因为倒数第一周没有上一个状态,还有就是每个状态dp[i][j]都初始化赋为days[i][j]来更新,这样一旦没有任何城市可以直飞当前城市,起码我们还可以享受当前城市的假期,最后要做的就是想上面所说在dp[i][0]中找最大值 #2 优化了空间复杂度,只用了一个一维的DP数组和一个临时一维数组,其中dp[i]表示在当前周,在城市i时已经获得的最大假期数,并且除了第一个数初始化为0,其余均初始化为整型最小值 #3 DFS + Memory

[LeetCode#562] Longest Line of Consecutive One in Matrix 矩阵中最长的连续1 Given a 01 matrix M, find the longest line of consecutive one in the matrix. The line could be horizontal, vertical, diagonal or anti-diagonal. Example: Input: [[0,1,1,0], [0,1,1,0], [0,0,0,1]] Output: 3 Hint: The number of elements in the given matrix will not exceed 10,000.

一个二维矩阵,让我们求矩阵中最长的连续1,连续方向任意,可以是水平,竖直,对角线或者逆对角线均可 (不能转弯) #1 四个方向分别来统计最长的连续1 水平竖直简单 对角线:mxn的矩阵,如果i是从0到m+n-1之间遍历,j是在i到0之间遍历,那么对角线的数字的坐标就为(i-j, j),逆对角线的坐标就为(m-1-(i-j), j) #2 DP 三维dp数组,其中dp[i][j][k]表示从开头遍历到数字nums[i][j]为止,第k种情况的连续1的个数,k的值为0,1,2,3,分别对应水平,竖直,对角线和逆对角线这四种情况 if (M[i][j] == 0) continue; for (int k = 0; k < 4; ++k) dp[i][j][k] = 1; if (j > 0) dp[i][j][0] += dp[i][j - 1][0]; // horizonal if (i > 0) dp[i][j][1] += dp[i - 1][j][1]; // vertical if (i > 0 && j < n - 1) dp[i][j][2] += dp[i - 1][j + 1][2]; // diagonal if (i > 0 && j > 0) dp[i][j][3] += dp[i - 1][j - 1][3]; // anti-diagonal res = max(res, max(dp[i][j][0], dp[i][j][1])); res = max(res, max(dp[i][j][2], dp[i][j][3])); #3 DFS 对每个1,在四个方向上走到头,连续1计数

[LeetCode#532] K-diff Pairs in an Array 数组中差为K的数对 Given an array of integers and an integer k, you need to find the number of unique k-diff pairs in the array. Here a k-diff pair is defined as an integer pair (i, j), where i and j are both numbers in the array and their absolute difference is k. Example 1: Input: [3, 1, 4, 1, 5], k = 2 Output: 2 Explanation: There are two 2-diff pairs in the array, (1, 3) and (3, 5). Although we have two 1s in the input, we should only return the number of unique pairs. Example 2: Input:[1, 2, 3, 4, 5], k = 1 Output: 4 Explanation: There are four 1-diff pairs in the array, (1, 2), (2, 3), (3, 4) and (4, 5). Example 3: Input: [1, 3, 1, 5, 4], k = 0 Output: 1 Explanation: There is one 0-diff pair in the array, (1, 1). Note: The pairs (i, j) and (j, i) count as the same pair. The length of the array won't exceed 10,000. All the integers in the given input belong to the range: [-1e7, 1e7].

一个含有重复数字的无序数组,还有一个整数k,让我们找出有多少对不重复的数对(i, j)使得i和j的差刚好为k #1 我们可以建立每个数字和其出现次数之间的映射,然后遍历哈希表中的数字,如果k为0且该数字出现的次数大于1,则结果res自增1;如果k不为0,且用当前数字加上k后得到的新数字也在数组中存在,则结果res自增1 #2 没有使用哈希表,而是使用了双指针,需要给数组排序,节省了空间的同时牺牲了时间。我们遍历排序后的数组,然后在当前数字之后找第一个和当前数之差不小于k的数字,若这个数字和当前数字之差正好为k,那么结果res自增1,然后遍历后面的数字去掉重复数字

[LeetCode#591] Tag Validator 标签验证器 Given a string representing a code snippet, you need to implement a tag validator to parse the code and return whether it is valid. A code snippet is valid if all the following rules hold: The code must be wrapped in a valid closed tag. Otherwise, the code is invalid. A closed tag (not necessarily valid) has exactly the following format : <TAG_NAME>TAG_CONTENT</TAG_NAME>. Among them, <TAG_NAME> is the start tag, and </TAG_NAME> is the end tag. The TAG_NAME in start and end tags should be the same. A closed tag is valid if and only if the TAG_NAME and TAG_CONTENT are valid. A valid TAG_NAME only contain upper-case letters, and has length in range [1,9]. Otherwise, the TAG_NAMEis invalid. A valid TAG_CONTENT may contain other valid closed tags, cdata and any characters (see note1) EXCEPTunmatched <, unmatched start and end tag, and unmatched or closed tags with invalid TAG_NAME. Otherwise, the TAG_CONTENT is invalid. A start tag is unmatched if no end tag exists with the same TAG_NAME, and vice versa. However, you also need to consider the issue of unbalanced when tags are nested. A < is unmatched if you cannot find a subsequent >. And when you find a < or </, all the subsequent characters until the next > should be parsed as TAG_NAME (not necessarily valid). The cdata has the following format : <![CDATA[CDATA_CONTENT]]>. The range of CDATA_CONTENT is defined as the characters between <![CDATA[ and the first subsequent ]]>. CDATA_CONTENT may contain any characters. The function of cdata is to forbid the validator to parse CDATA_CONTENT, so even it has some characters that can be parsed as tag (no matter valid or invalid), you should treat it as regular characters. Valid Code Examples: Input: "<DIV>This is the first line <![CDATA[<div>]]></DIV>" Output: True Explanation: The code is wrapped in a closed tag : <DIV> and </DIV>. The TAG_NAME is valid, the TAG_CONTENT consists of some characters and cdata. Although CDATA_CONTENT has unmatched start tag with invalid TAG_NAME, it should be considered as plain text, not parsed as tag. So TAG_CONTENT is valid, and then the code is valid. Thus return true. Input: "<DIV>>> ![cdata[]] <![CDATA[<div>]>]]>]]>>]</DIV>" Output: True Explanation: We first separate the code into : start_tag|tag_content|end_tag. start_tag -> "<DIV>" end_tag -> "</DIV>" tag_content could also be separated into : text1|cdata|text2. text1 -> ">> ![cdata[]] " cdata -> "<![CDATA[<div>]>]]>", where the CDATA_CONTENT is "<div>]>" text2 -> "]]>>]" The reason why start_tag is NOT "<DIV>>>" is because of the rule 6. The reason why cdata is NOT "<![CDATA[<div>]>]]>]]>" is because of the rule 7. Invalid Code Examples: Input: "<A> <B> </A> </B>" Output: False Explanation: Unbalanced. If "<A>" is closed, then "<B>" must be unmatched, and vice versa. Input: "<DIV> div tag is not closed <DIV>" Output: False Input: "<DIV> unmatched < </DIV>" Output: False Input: "<DIV> closed tags with invalid tag name <b>123</b> </DIV>" Output: False Input: "<DIV> unmatched tags with invalid tag name </1234567890> and <CDATA[[]]> </DIV>" Output: False Input: "<DIV> unmatched start tag <B> and unmatched end tag </C> </DIV>" Output: False Note: For simplicity, you could assume the input code (including the any characters mentioned above) only contain letters, digits, '<','>','/','!','[',']' and ' '.

一个字符串,其实是html的代码,让我们验证其写法是否正确。规定了八条规则,比如说必须是封闭的,标签名必须都是大写,并且不能超过9个字符,还规定了CDATA的一些格式规范,并且给了一些实例 #1 对于这种成对匹配的问题肯定是要用栈stack的,就像之前的匹配括号的问题。 #2 正则式 regex cdata("<!\\[CDATA\\[.*?\\]\\]>"), tag("<([A-Z]{1,9})>[^<]*</\\1>"); code = regex_replace(code, cdata, "c"); string pre = code; while ( pre != (code = regex_replace(code, tag, "t")) ) pre = code; return "t" == code;

[LeetCode#556] Next Greater Element III 下一个较大的元素之三 Given a positive 32-bit integer n, you need to find the smallest 32-bit integer which has exactly the same digits existing in the integer n and is greater in value than n. If no such positive 32-bit integer exists, you need to return -1. Example 1: Input: 12 Output: 21 Example 2: Input: 21 Output: -1

一个数字,让我们对各个位数重新排序,求出刚好比给定数字大的一种排序,如果不存在就返回-1 从后往前遍历,找到第一个大于左数第二个的数字交换,然后把转折点之后的数字按升序排列就是最终的结果 比如12443322,这个数字的重排序结果应该为13222344

[LeetCode#600] Non-negative Integers without Consecutive Ones 非负整数不包括连续的1 Given a positive integer n, find the number of non-negative integers less than or equal to n, whose binary representations do NOT contain consecutive ones. Example 1: Input: 5 Output: 5 Explanation: Here are the non-negative integers <= 5 with their corresponding binary representations: 0 : 0 1 : 1 2 : 10 3 : 11 4 : 100 5 : 101 Among them, only integer 3 disobeys the rule (two consecutive ones) and the other 5 satisfy the rule. Note: 1 <= n <= 109

一个数字,让我们求不大于这个数字的所有数字中,其二进制的表示形式中没有连续1的个数。 #1 DP zero[i] 是长度为i的二进制字符串中没有连续1,并且结尾是0的情况个数。one[i] 是同情况但结尾是1的情况个数 zero[0] = one[0] = 1; zero[i] = zero[i - 1] + one[i - 1] one[i] = zero[i - 1] 要将大于num的情况去掉:如果input本身就没有连续的1,我们的DP就没有多算;否则,input就一定有00或11的情况,从高位向低位扫描,11说明我们算的情况比input小,没有多算;00说明我们多算了01的情况,多算了one[lower]个。 [Mine]zero[i]肯定包括zero[i - 1]所有情况,并且加上one[i - 1]所有情况左移一位,低位补0;one[i]相当于zero[i - 1]所有情况左移一位,低位补1 00时没有多算10的情况,因为10前必定是0,即010,而input一定是100,因为如果是000中后两个00,那么10的情况在前个00时已经算在01的情况中的 #2 长度为k的二进制数字符串没有连续的1的个数是一个斐波那契数列f(k),例如f(5) = f(00000~11111) = f(00000~01111) + f(10000~10111) = f(4) + f(3) 计算到f(31)即可; 从给定数字的最高位开始遍历,如果某一位是1,后面有k位,就加上f(k),因为如果我们把当前位变成0,那么后面k位就可以直接从斐波那契数列中取值了。然后标记pre为1,再往下遍历,如果遇到0位,则pre标记为0。如果当前位是1,pre也是1,那么直接返回结果。最后循环退出后我们要加上数字本身这种情况(即最高位为1,后面01相间的这个数字) [Mine]能看出DP和斐波那契数列,都很强。

[LeetCode#523] Continuous Subarray Sum 连续的子数组之和 Given a list of non-negative numbers and a target integer k, write a function to check if the array has a continuous subarray of size at least 2 that sums up to the multiple of k, that is, sums up to n*k where n is also an integer. Example 1: Input: [23, 2, 4, 6, 7], k=6 Output: True Explanation: Because [2, 4] is a continuous subarray of size 2 and sums up to 6. Example 2: Input: [23, 2, 6, 4, 7], k=6 Output: True Explanation: Because [23, 2, 6, 4, 7] is an continuous subarray of size 5 and sums up to 42. Note: The length of the array won't exceed 10,000. You may assume the sum of all the numbers is in the range of a signed 32-bit integer.

一个数组和一个数字k,让我们求是否存在这样的一个连续的子数组,该子数组的数组之和可以整除k 若数字a和b分别除以数字c,若得到的余数相同,那么(a-b)必定能够整除c 保存所有出现过的余数,如果当前的累加和除以k得到的余数在set中已经存在了,那么说明之前必定有一段子数组和可以整除k。需要注意的是k为0的情况,由于无法取余,我们就把当前累加和放入set中。 hashmap记录余数及其对应Index,用index来确保子数组至少需要两个数字

[LeetCode#560] Subarray Sum Equals K 子数组和为K Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k. Example 1: Input:nums = [1,1,1], k = 2 Output: 2 Note: The length of the array is in range [1, 20,000]. The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].

一个数组,让我们求和为k的连续子数组的个数 #1 累加和 #2 用一个哈希表来建立连续子数组之和跟其出现次数之间的映射,初始化要加入{0,1}这对映射

[LeetCode#553] Optimal Division 最优分隔 Given a list of positive integers, the adjacent integers will perform the float division. For example, [2,3,4] -> 2 / 3 / 4. However, you can add any number of parenthesis at any position to change the priority of operations. You should find out how to add parenthesis to get the maximum result, and return the corresponding expression in string format. Your expression should NOT contain redundant parenthesis. Example: Input: [1000,100,10,2] Output: "1000/(100/10/2)" Explanation: 1000/(100/10/2) = 1000/((100/10)/2) = 200 However, the bold parenthesis in "1000/((100/10)/2)" are redundant, since they don't influence the operation priority. So you should return "1000/(100/10/2)". Other cases: 1000/(100/10)/2 = 50 1000/(100/(10/2)) = 50 1000/100/10/2 = 0.5 1000/100/(10/2) = 2 Note: The length of the input array is [1, 10]. Elements in the given array will be in range [2, 1000]. There is only one optimal division for each test case.

一个数组,让我们确定除法的顺序,从而得到值最大的运算顺序,并且不能加多余的括号。 x1 / x2 / x3 / ... / xn 那么我们如何加括号使得其值最大呢,那么就是将x2后面的除数都变成乘数 x1 / (x2 / x3 / ... / xn) = x1/x2*x3*....*xn 变成了一个道简单的字符串操作的题目了

[LeetCode#507] Perfect Number 完美数字 We define the Perfect Number is a positive integer that is equal to the sum of all its positive divisors except itself. Now, given an integer n, write a function that returns true when it is a perfect number and false when it is not. Example: Input: 28 Output: True Explanation: 28 = 1 + 2 + 4 + 7 + 14 Note: The input number n will not exceed 100,000,000. (1e8)

一个整数等于除其自身之外的所有的因子之和 #1 找其他因子的范围是[2, sqrt(n)]。我们遍历这之间所有的数字,如果可以被n整除,那么我们把i和num/i都加上,对于n如果是平方数的话,那么我们此时相同的因子加来两次,所以我们要减掉一次。还有就是在遍历的过程中如果累积和sum大于n了,直接返回false即可。在循环结束后,我们看sum是否和num相等 #2 在给定的n的范围内其实只有五个符合要求的完美数字 return num==6 || num==28 || num==496 || num==8128 || num==33550336;

[LeetCode#467] Unique Substrings in Wraparound String 封装字符串中的独特子字符串 Consider the string s to be the infinite wraparound string of "abcdefghijklmnopqrstuvwxyz", so s will look like this: "...zabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd....". Now we have another string p. Your job is to find out how many unique non-empty substrings of p are present in s. In particular, your input is the string p and you need to output the number of different non-empty substrings of p in the string s. Note: p consists of only lowercase English letters and the size of p might be over 10000. Example 1: Input: "a" Output: 1 Explanation: Only the substring "a" of string "a" is in the string s. Example 2: Input: "cac" Output: 2 Explanation: There are two substrings "a", "c" of string "cac" in the string s. Example 3: Input: "zab" Output: 6 Explanation: There are six substrings "z", "a", "b", "za", "ab", "zab" of string "zab" in the string s.

一个无限长的封装字符串(26个字符按顺序无限循环组成的),然后又给了我们另一个字符串p,问我们p有多少非空子字符串在封装字符串中。题意的p的子字符串要么是单一的字符,要么是按字母顺序的子字符串。 [Mine]关键:字符串的子串中以原字符串最后一个字符为最后一个字符的子串数量等于字符串长度。 例如:abcd这个字符串,以d结尾的子字符串有abcd, bcd, cd, d,四个子串 坑1:z->a 对p中每个字符,如果它和之前是按照字母顺序的(包括z->a),且到此字母顺序子串长为len,那么以它结尾的子串数为len。 坑2: 同一个字母可能出现在不同的字母顺序子串中,这要取子串长大的 最后,累加26个字母在p中以此字母结尾的字母顺序子串长度。

[LeetCode#540] Single Element in a Sorted Array 有序数组中的单独元素 Given a sorted array consisting of only integers where every element appears twice except for one element which appears once. Find this single element that appears only once. Example 1: Input: [1,1,2,3,3,4,4,8,8] Output: 2 Example 2: Input: [3,3,7,7,10,11,11] Output: 10 Note: Your solution should run in O(log n) time and O(1) space.

一个有序数组,说是所有的元素都出现了两次,除了一个元素,让我们找到这个元素。 由于O(logn)限制,无法直线查找,或异或落单。 #1 要利用有序来折半查找 利用折半后,判断左右奇偶数来判断。 如果当前数字出现两次的话,我们可以通过数组的长度跟当前位置的关系,计算出右边和当前数字不同的数字的总个数,如果是偶数个,说明落单数左半边,反之则在右半边。 #2 trick: 亦或1可以将坐标两两归为一对,比如0和1,2和3,4和5等等。而亦或1可以直接找到你的小伙伴。用这个trick可以简化#1的奇偶判断。 #3 trick: 对mid进行了处理,强制使其成为小伙伴对儿中的第一个位置,然后跟另一个小伙伴比较大小:if (mid % 2 == 1) --mid; if (mid % 2 == 1) --mid;

[LeetCode#554] Brick Wall 砖头墙壁 There is a brick wall in front of you. The wall is rectangular and has several rows of bricks. The bricks have the same height but different width. You want to draw a vertical line from the top to the bottom and cross the leastbricks. The brick wall is represented by a list of rows. Each row is a list of integers representing the width of each brick in this row from left to right. If your line go through the edge of a brick, then the brick is not considered as crossed. You need to find out how to draw the line to cross the least bricks and return the number of crossed bricks. You cannot draw a line just along one of the two vertical edges of the wall, in which case the line will obviously cross no bricks. Example: Input: [[1,2,2,1], [3,1,2], [1,3,2], [2,4], [3,1,2], [1,3,1,1]] Output: 2 Explanation: Note: The width sum of bricks in different rows are the same and won't exceed INT_MAX. The number of bricks in each row is in range [1,10,000]. The height of wall is in range [1,10,000]. Total number of bricks of the wall won't exceed 20,000.

一个砖头墙壁,上面由不同的长度的砖头组成,让我们选个地方从上往下把墙劈开,使得被劈开的砖头个数最少 #1 使用一个哈希表来建立每一个断点的长度和其出现频率之间的映射,这样只要我们从断点频率出现最多的地方劈墙,损坏的板砖一定最少

[LeetCode#462] Minimum Moves to Equal Array Elements II 最少移动次数使数组元素相等之二 Given a non-empty integer array, find the minimum number of moves required to make all array elements equal, where a move is incrementing a selected element by 1 or decrementing a selected element by 1. You may assume the array's length is at most 10,000. Example: Input: [1,2,3] Output: 2 Explanation: Only two moves are needed (remember each move increments or decrements one element): [1,2,3] => [2,2,3] => [2,2,2]

一个长度为n的数组,每次对任意一个数字加1或者减1,让我们用最少的次数让数组所有值相等。 #1 O(nlgn) 首先给数组排序,那么我们最终需要变成的相等的数字就是中间的数,如果数组有奇数个,那么就是最中间的那个数字;如果是偶数个,那么就是中间两个数的区间中的任意一个数字。而两端的数字变成中间的一个数字需要的步数实际上就是两端数字的距离 #2 O(n) nth_element #3 O(nlgn) 改进版的暴力破解法: 它遍历了所有的数字,让每个数字都当作最后相等的值,然后算法出来总步数,每次和res比较 快速计算总步数: 排序, then, index i , value k (k = nums[i]) Total Steps to index i = 2 * i * k - n * k + sum - 2 * curSum [Mine]画个图,就好理解,排序好后是一个三角形。用i, k, sum, curSum就可以计算出平衡到index i的步数。

[LeetCode#555] Split Concatenated Strings 分割串联字符串 Given a list of strings, you could concatenate these strings together into a loop, where for each string you could choose to reverse it or not. Among all the possible loops, you need to find the lexicographically biggest string after cutting the loop, which will make the looped string into a regular one. Specifically, to find the lexicographically biggest string, you need to experience two phases: Concatenate all the strings into a loop, where you can reverse some strings or not and connect them in the same order as given. Cut and make one breakpoint in any place of the loop, which will make the looped string into a regular one starting from the character at the cutpoint. And your job is to find the lexicographically biggest one among all the possible regular strings. Example: Input: "abc", "xyz" Output: "zyxcba" Explanation: You can get the looped string "-abcxyz-", "-abczyx-", "-cbaxyz-", "-cbazyx-", where '-' represents the looped status. The answer string came from the fourth looped one, where you could cut from the middle character 'a' and get "zyxcba". Note: The input strings will only contain lowercase letters. The total length of all the strings will not over 1,000.

一些字符串,让我们将其连接起来,连接的时候对于每个字符串我们可以选择翻转或者不翻转,在形成的大的字符串上找一个位置cut掉,将该位置当作首字符,前面的字符串移动到末尾去,问怎么cut能使字符串的字母顺序大 只有cut所在的字符串的翻转可能不按规律,其他的字符都是按照字母顺序来确定要不要翻转的 对于在哪个字符串cut,只能遍历 小优化,如果cut位置的字母大于等于结果res的首字母,我们才进行对比更新。 [Mine]除了反转,cut,字符串的相对位置是不变的。

[LeetCode#587] Erect the Fence 竖立栅栏 There are some trees, where each tree is represented by (x,y) coordinate in a two-dimensional garden. Your job is to fence the entire garden using the minimum length of rope as it is expensive. The garden is well fenced only if all the trees are enclosed. Your task is to help find the coordinates of trees which are exactly located on the fence perimeter. Example 1: Input: [[1,1],[2,2],[2,0],[2,4],[3,3],[4,2]] Output: [[1,1],[2,0],[4,2],[3,3],[2,4]] Explanation: Example 2: Input: [[1,2],[2,2],[4,2]] Output: [[1,2],[2,2],[4,2]] Explanation: Even you only have trees in a line, you need to use rope to enclose them. Note: All trees should be enclosed together. You cannot cut the rope to enclose trees that will separate them in more than one group. All input integers will range from 0 to 100. The garden has at least one tree. All coordinates are distinct. Input points have NO order. No order required for output.

一些树,每个树都有其特定的坐标,让我们用最少的栅栏将其全部包住,让我们找出在栅栏边上的树。 凸包问题,就是平面上给了一堆点,让我们找出一个多边形,正好包括了所有的点。 卷包裹Gift wrapping算法,又叫Jarvis march算法。这种算法的核心像一种卷包裹的操作,比如说我们把每个点当成墙上的钉子,然后我们有一个皮筋,我们直接将皮筋撑的老大,然后套在所有钉子上松手,其自动形成的形状就是要求的凸包 1. 取一个最左边的也就是横坐标最小的点 2. 利用向量的叉积来解决这个问题,定义二维向量<x1,y1>和<x2,y2>的叉积为一个实数Cp=x1*y2-x2*y1 向量的叉积是不满足交换律的 向量A乘以向量B 如果为正则为A逆时针旋转向B 否则为顺时针 利用向量 我们可以比较哪个点"更外侧" 卷包裹算法的复杂度是O(NH) N是全部的点数 H是最终在凸包上的点数 [Mine]利用向量的叉积来找第一个确定极点的最外侧邻居,这样不断找下去直到第一个极点。

[LeetCode#415] Add Strings 字符串相加 Given two non-negative numbers num1 and num2 represented as string, return the sum of num1 and num2. Note: The length of both num1 and num2 is < 5100. Both num1 and num2 contains only digits 0-9. Both num1 and num2 does not contain any leading zero. You must not use any built-in BigInteger library or convert the inputs to integer directly.

一位一位相加,然后算和算进位,最后根据进位情况看需不需要补一个高位

[LeetCode#573] Squirrel Simulation 松鼠模拟 There's a tree, a squirrel, and several nuts. Positions are represented by the cells in a 2D grid. Your goal is to find the minimal distance for the squirrel to collect all the nuts and put them under the tree one by one. The squirrel can only take at most one nut at one time and can move in four directions - up, down, left and right, to the adjacent cell. The distance is represented by the number of moves. Example 1: Input: Height : 5 Width : 7 Tree position : [2,2] Squirrel : [4,4] Nuts : [[3,0], [2,5]] Output: 12 Explanation: Note: All given positions won't overlap. The squirrel can take at most one nut at one time. The given positions of nuts have no order. Height and width are positive integers. 3 <= height * width <= 10,000. The given positions contain at least one nut, only one tree and one squirrel.

一只小松鼠,一堆在不同位置的粟子,还有一棵树,小松鼠目标是把所有的粟子都运到树的位置,问怎样的顺序可以使用最少的步数。 如果小松鼠本身就在树的位置,那么把所有的栗子运回树的步数就是一个定值 关键就在于决定小松鼠首先去哪个粟子那 假设小松树最先应该去粟子i,那么我们假设粟子i到树的距离为x,小松鼠到粟子i的距离为y,那么如果小松鼠不去粟子i,累加步数就是2x,如果小松鼠去粟子i,累加步数就是x+y,我们希望x+y尽可能的小于2x,那么就是y尽可能小于x,即x-y越大越好。这样我们遍历每个粟子,找出x-y最大的那个,让小松鼠先去捡就好了。

[LeetCode#530] Minimum Absolute Difference in BST 二叉搜索树的最小绝对差 Given a binary search tree with non-negative values, find the minimum absolute difference between values of any two nodes. Example: Input: 1 \ 3 / 2 Output: 1 Explanation: The minimum absolute difference is 1, which is the difference between 2 and 1 (or between 2 and 3). Note: There are at least two nodes in this BST.

一棵二叉搜索树,让我们求任意个节点值之间的最小绝对差。 #1 最小绝对差肯定在相邻的两个节点值之间产生,中序遍历 #2 先序遍历 两个变量low和high来分别表示上下界,初始化为int的极值,然后我们在递归函数中,分别用上下界和当前节点值的绝对差来更新结果res if (low != INT_MIN) res = min(res, root->val - low); if (high != INT_MAX) res = min(res, high - root->val); helper(root->left, low, root->val, res); helper(root->right, root->val, high, res);

[LeetCode#545] Boundary of Binary Tree 二叉树的边界 Given a binary tree, return the values of its boundary in anti-clockwise direction starting from root. Boundary includes left boundary, leaves, and right boundary in order without duplicate nodes. Left boundary is defined as the path from root to the left-most node. Right boundary is defined as the path from root to the right-most node. If the root doesn't have left subtree or right subtree, then the root itself is left boundary or right boundary. Note this definition only applies to the input binary tree, and not applies to any subtrees. The left-most node is defined as a leaf node you could reach when you always firstly travel to the left subtree if exists. If not, travel to the right subtree. Repeat until you reach a leaf node. The right-most node is also defined by the same way with left and right exchanged. Example 1 Input: 1 \ 2 / \ 3 4 Ouput: [1, 3, 4, 2] Explanation: The root doesn't have left subtree, so the root itself is left boundary. The leaves are node 3 and 4. The right boundary are node 1,2,4. Note the anti-clockwise direction means you should output reversed right boundary. So order them in anti-clockwise without duplicates and we have [1,3,4,2]. Example 2 Input: ____1_____ / \ 2 3 / \ / 4 5 6 / \ / \ 7 8 9 10 Ouput: [1,2,4,7,8,9,10,6,3] Explanation: The left boundary are node 1,2,4. (4 is the left-most node according to definition) The leaves are node 4,7,8,9,10. The right boundary are node 1,3,6,10. (10 is the right-most node). So order them in anti-clockwise without duplicate nodes we have [1,2,4,7,8,9,10,6,3].

一棵二叉树,让我们以逆时针的顺序来输出树的边界,按顺序分别为左边界,叶结点和右边界。 按顺序求出左边界结点,叶结点,和右边界结点 #1 递归 求左边界结点的函数,如果当前结点不存在,或者没有子结点,我们直接返回。否则就把当前结点值加入结果res中,然后看如果左子结点存在,就对其调用递归函数,反之如果左子结点不存在,那么对右子结点调用递归函数 先序遍历找左边界,后序遍历找右边界 #2 用一个递归来扫描三类节点,用flag来调整左右支扫描优先级和先后序 #3 迭代

[LeetCode#583] Delete Operation for Two Strings 两个字符串的删除操作 Given two words word1 and word2, find the minimum number of steps required to make word1 and word2 the same, where in each step you can delete one character in either string. Example 1: Input: "sea", "eat" Output: 2 Explanation: You need one step to make "sea" to "ea" and another step to make "eat" to "ea". Note: The length of given words won't exceed 500. Characters in given words can only be lower-case letters.

两个单词,问我们最少需要多少步可以让两个单词相等,每一步我们可以在任意一个单词中删掉一个字符 #1 两个单词最长的相同子序列的长度,并乘以2,被两个单词的长度之和减,就是最少步数了。 Longest Common Subsequence(LCS) dp[i][j]表示word1的前i个字符和word2的前j个字符组成的两个单词的最长公共子序列的长度。 if (word1[i - 1] == word2[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; } else { dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); } return n1 + n2 - 2 * dp[n1][n2]; #2 dp[i][j]表示word1的前i个字符和word2的前j个字符组成的两个单词,能使其变相同的最小的步数 if (word1[i - 1] == word2[j - 1]) { dp[i][j] = dp[i - 1][j - 1]; } else { dp[i][j] = 1 + min(dp[i - 1][j], dp[i][j - 1]); } return dp[n1][n2]; #3 递归 + Memory of #2

[LeetCode#599] Minimum Index Sum of Two Lists 两个表单的最小坐标和 Suppose Andy and Doris want to choose a restaurant for dinner, and they both have a list of favorite restaurants represented by strings. You need to help them find out their common interest with the least list index sum. If there is a choice tie between answers, output all of them with no order requirement. You could assume there always exists an answer. Example 1: Input: ["Shogun", "Tapioca Express", "Burger King", "KFC"] ["Piatti", "The Grill at Torrey Pines", "Hungry Hunter Steakhouse", "Shogun"] Output: ["Shogun"] Explanation: The only restaurant they both like is "Shogun". Example 2: Input: ["Shogun", "Tapioca Express", "Burger King", "KFC"] ["KFC", "Shogun", "Burger King"] Output: ["Shogun"] Explanation: The restaurant they both like and have the least index sum is "Shogun" with index sum 1 (0+1). Note: The length of both lists will be in the range of [1, 1000]. The length of strings in both lists will be in the range of [1, 30]. The index is starting from 0 to the list length minus 1. No duplicates in both lists.

两个字符串数组,让我们找到坐标位置之和最小的相同的字符串。 建立数据和其位置坐标之间的映射。

[LeetCode#582] Kill Process 结束进程 Given n processes, each process has a unique PID (process id) and its PPID (parent process id). Each process only has one parent process, but may have one or more children processes. This is just like a tree structure. Only one process has PPID that is 0, which means this process has no parent process. All the PIDs will be distinct positive integers. We use two list of integers to represent a list of processes, where the first list contains PID for each process and the second list contains the corresponding PPID. Now given the two lists, and a PID representing a process you want to kill, return a list of PIDs of processes that will be killed in the end. You should assume that when a process is killed, all its children processes will be killed. No order is required for the final answer. Example 1: Input: pid = [1, 3, 10, 5] ppid = [3, 0, 5, 3] kill = 5 Output: [5,10] Explanation: 3 / \ 1 5 / 10 Kill 5 will also kill 10. Note: The given kill id is guaranteed to be one of the given PIDs. n >= 1.

两个数组,一个是进程的数组,还有一个是进程数组中的每个进程的父进程组成的数组。题目中说结束了某一个进程,其所有的子进程都需要结束,由于一个进程可能有多个子进程 #1 迭代+queue 一个哈希表,建立进程和其所有子进程之间的映射,然后我们首先把要结束的进程放入一个队列queue中,然后while循环,每次取出一个进程,将其加入结果res中,然后遍历其所有子进程,将所有子进程都排入队列中,这样我们就能结束所有相关的进程, #2 递归

[LeetCode#432] All O`one Data Structure 全O(1)的数据结构 Implement a data structure supporting the following operations: Inc(Key) - Inserts a new key with value 1. Or increments an existing key by 1. Key is guaranteed to be a non-empty string. Dec(Key) - If Key's value is 1, remove it from the data structure. Otherwise decrements an existing key by 1. If the key does not exist, this function does nothing. Key is guaranteed to be a non-empty string. GetMaxKey() - Returns one of the keys with maximal value. If no element exists, return an empty string "". GetMinKey() - Returns one of the keys with minimal value. If no element exists, return an empty string "". Challenge: Perform all these in O(1) time complexity.

为了让找到key在O(1)内,要hashmap 为了让GetMaxKey(),GetMinKey()在O(1),需要按照value大小排序,并在Inc(Key)和Dec(Key)以O(1)将相同value的key Set调整到排序好的位置(可能拆解或合并set)

[LeetCode#543] Diameter of Binary Tree 二叉树的直径 Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is the length of the longestpath between any two nodes in a tree. This path may or may not pass through the root. Example: Given a binary tree 1 / \ 2 3 / \ 4 5 Return 3, which is the length of the path [4,2,1,3] or [5,2,1,3]. Note: The length of path between two nodes is represented by the number of edges between them.

二叉树的直径,并告诉了我们直径就是两点之间的最远距离 根结点1的左右两个子树的深度之和再加1 #1 递归 对每一个结点求出其左右子树深度之和,再加上1就可以更新结果res了。为了减少重复计算,我们用哈希表建立每个结点和其深度之间的映射 [Mine]注意:结果不一定是要经过根节点的。所以要计算每个节点的左右子树深度

[LeetCode#576] Out of Boundary Paths 出界的路径 There is an m by n grid with a ball. Given the start coordinate (i,j) of the ball, you can move the ball to adjacent cell or cross the grid boundary in four directions (up, down, left, right). However, you can at most move N times. Find out the number of paths to move the ball out of grid boundary. The answer may be very large, return it after mod 109 + 7. Example 1: Input:m = 2, n = 2, N = 2, i = 0, j = 0 Output: 6 Explanation: Example 2: Input:m = 1, n = 3, N = 3, i = 0, j = 1 Output: 12 Explanation: Note: Once you move the ball out of boundary, you cannot move it back. The length and height of the grid is in range [1,50]. N is in range [0,50].

二维的数组,某个位置放个足球,每次可以在上下左右四个方向中任意移动一步,总共可以移动N步,问我们总共能有多少种移动方法能把足球移除边界,由于结果可能是个巨大的数,所以让我们对一个大数取余。 对于这种结果很大的数如果用递归解法很容易爆栈,所以最好考虑使用DP来解。 #1 三维的DP数组,其中dp[k][i][j]表示总共走k步,从(i,j)位置走出边界的总路径数。 对于dp[k][i][j],走k步出边界的总路径数等于其周围四个位置的走k-1步出边界的总路径数之和 最后只要返回dp[N][i][j]就是所求结果了 long long v1 = (x == 0) ? 1 : dp[k - 1][x - 1][y]; long long v2 = (x == m - 1) ? 1 : dp[k - 1][x + 1][y]; long long v3 = (y == 0) ? 1 : dp[k - 1][x][y - 1]; long long v4 = (y == n - 1) ? 1 : dp[k - 1][x][y + 1]; dp[k][x][y] = (v1 + v2 + v3 + v4) % 1000000007; [Mine]这是从边界倒推到在特定步数限制下能走到各个cell的不同方式数量 #2 BFS + memory BFS搜索,以(i, j)为起始点,dp[k][x][y]表示用了k步,进入(x, y)位置的路径数,由于dp[k][x][y]只依赖于dp[k-1][x][y],所以我们可以用一个二维dp数组来代替,初始化dp[i][j]为1 N次循环,每次都新建一个mxn大小的临时数组t,然后就是对于遍历到的每个位置,都遍历其四个相邻位置,如果相邻位置越界了,那么我们用当前位置的dp值更新结果res,因为此时dp值的意义就是从(i,j)到越界位置的路径数。 [Mine]从(i, j)为起始点,走N步,一旦走出边界,就将dp累加到res中

[LeetCode#401] Binary Watch 二进制表 A binary watch has 4 LEDs on the top which represent the hours (0-11), and the 6 LEDs on the bottom represent the minutes (0-59). Each LED represents a zero or one, with the least significant bit on the right. For example, the above binary watch reads "3:25". Given a non-negative integer n which represents the number of LEDs that are currently on, return all possible times the watch could represent. Example: Input: n = 1 Return: ["1:00", "2:00", "4:00", "8:00", "0:01", "0:02", "0:04", "0:08", "0:16", "0:32"] Note: The order of output does not matter. The hour must not contain a leading zero, for example "01:00" is not valid, it should be "1:00". The minute must be consist of two digits and may contain a leading zero, for example "10:2" is not valid, it should be "10:02".

二进制手表,告诉我们有N个灯是亮的,问我们可能的时间。 #1利用到了bitset这个类,可以将任意进制数转为二进制,而且又用到了count函数,用来统计1的个数。那么时针从0遍历到11,分针从0遍历到59,然后我们把时针的数组左移6位加上分针的数值,然后统计1的个数,即为亮灯的个数,我们遍历所有的情况,当其等于num的时候,存入结果res中 #2 如果总共要取num个,我们在小时集合里取i个,算出和,然后在分钟集合里去num-i个求和,如果两个都符合题意,那么加入结果中即可。集合中取出几个的方法可以用递归计算Combinations #3 二进制表再叼也就72种情况,全给你列出来,然后采用跟上面那种解法相同的思路,时针集合取k个,分针集合取num-k个,然后存入结果中即可 [Mine]由于是有限个数组合。想怎么遍历都可以

[LeetCode#525] Contiguous Array 邻近数组 Given a binary array, find the maximum length of a contiguous subarray with equal number of 0 and 1. Example 1: Input: [0,1] Output: 2 Explanation: [0, 1] is the longest contiguous subarray with equal number of 0 and 1. Example 2: Input: [0,1,0] Output: 2 Explanation: [0, 1] (or [1, 0]) is a longest contiguous subarray with equal number of 0 and 1. Note: The length of the given binary array will not exceed 50,000.

二进制的数组,让我们找邻近的子数组使其0和1的个数相等 note:对于求子数组的问题,我们需要时刻记着求累积和是一种很犀利的工具 #1 遇到1就加1,遇到0,就减1,这样如果某个子数组和为0,就说明0和1的个数相等。一个哈希表建立子数组之和跟结尾位置的坐标之间的映射。如果某个子数组之和在哈希表里存在了,说明当前子数组减去哈希表中存的那个子数字,得到的结果是中间一段子数组之和,必然为0,说明0和1的个数相等,我们更新结果res

[LeetCode#439] Ternary Expression Parser 三元表达式解析器 Given a string representing arbitrarily nested ternary expressions, calculate the result of the expression. You can always assume that the given expression is valid and only consists of digits 0-9, ?, :, T and F (T and Frepresent True and False respectively). Note: The length of the given string is ≤ 10000. Each number will contain only one digit. The conditional expressions group right-to-left (as usual in most languages). The condition will always be either T or F. That is, the condition will never be a digit. The result of the expression will always evaluate to either a digit 0-9, T or F. Example 1: Input: "T?2:3" Output: "2" Explanation: If true, then result is 2; otherwise result is 3. Example 2: Input: "F?1:T?4:5" Output: "4" Explanation: The conditional expressions group right-to-left. Using parenthesis, it is read/evaluated as: "(F ? 1 : (T ? 4 : 5))" "(F ? 1 : (T ? 4 : 5))" -> "(F ? 1 : 4)" or -> "(T ? 4 : 5)" -> "4" -> "4" Example 3: Input: "T?T?F:5:3" Output: "F" Explanation: The conditional expressions group right-to-left. Using parenthesis, it is read/evaluated as: "(T ? (T ? F : 5) : 3)" "(T ? (T ? F : 5) : 3)" -> "(T ? F : 3)" or -> "(T ? F : 5)" -> "F" -> "F"

从右边开始找到第一个问号,然后先处理这个三元表达式,然后再一步一步向左推,这也符合程序是从右向左执行的特点。 #1 stack #2 find_last_of

[LeetCode#417] Pacific Atlantic Water Flow 太平洋大西洋水流 Given an m x n matrix of non-negative integers representing the height of each unit cell in a continent, the "Pacific ocean" touches the left and top edges of the matrix and the "Atlantic ocean" touches the right and bottom edges. Water can only flow in four directions (up, down, left, or right) from a cell to another one with height equal or lower. Find the list of grid coordinates where water can flow to both the Pacific and Atlantic ocean. Note: The order of returned grid coordinates does not matter. Both m and n are less than 150. Example: Given the following 5x5 matrix: Pacific ~ ~ ~ ~ ~ ~ 1 2 2 3 (5) * ~ 3 2 3 (4) (4) * ~ 2 4 (5) 3 1 * ~ (6) (7) 1 4 5 * ~ (5) 1 1 2 4 * * * * * * Atlantic Return: [[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (positions with parentheses in above matrix).

从边缘当作起点开始遍历搜索,然后标记能到达的点位true,分别标记出pacific和atlantic能到达的点,那么最终能返回的点就是二者均为true的点 #1 DFS #2 BFS [Mine]DFS或BFS从海岸边找到制高点

[LeetCode#437] Path Sum III 二叉树的路径和之三 You are given a binary tree in which each node contains an integer value. Find the number of paths that sum to a given value. The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes). The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000. Example: root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8 10 / \ 5 -3 / \ \ 3 2 11 / \ \ 3 -2 1 Return 3. The paths that sum to 8 are: 1. 5 -> 3 2. 5 -> 2 -> 1 3. -3 -> 11

先序遍历二叉树 哈希表来建立所有的前缀路径之和跟其个数之间的映射,然后看子路径之和有没有等于给定值的 [Mine]I think #3 is wrong.

[LeetCode#491] Increasing Subsequences 递增子序列 Given an integer array, your task is to find all the different possible increasing subsequences of the given array, and the length of an increasing subsequence should be at least 2 . Example: Input: [4, 6, 7, 7] Output: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]] Note: The length of the given array will not exceed 15. The range of integer in the given array is [-100,100]. The given array may contain duplicates, and two equal integers should also be considered as a special case of increasing sequence.

先找出所有的子序列,从中找出递增的 检查 1. 序列长度大于等于2 2.递增 可以在记录结果时用set来去除重复项 也可以在递归过程中,用set来避免选用重复项 递归 迭代 [Mine]记录所有已知的大于0的升序序列,将新数字延长可能的升序序列,自己也是一个长度为1的升序序列。一旦长度大于等于3,记录在结果中。

[LeetCode#565] Array Nesting 数组嵌套 A zero-indexed array A consisting of N different integers is given. The array contains all integers in the range [0, N - 1]. Sets S[K] for 0 <= K < N are defined as follows: S[K] = { A[K], A[A[K]], A[A[A[K]]], ... }. Sets S[K] are finite for each K and should NOT contain duplicates. Write a function that given an array A consisting of N integers, return the size of the largest set S[K] for this array. Example 1: Input: A = [5,4,0,3,1,6,2] Output: 4 Explanation: A[0] = 5, A[1] = 4, A[2] = 0, A[3] = 3, A[4] = 1, A[5] = 6, A[6] = 2. One of the longest S[K]: S[0] = {A[0], A[5], A[6], A[2]} = {5, 6, 2, 0} Note: N is an integer within the range [1, 20,000]. The elements of A are all distinct. Each element of array A is an integer within the range [0, N-1].

其实就是值变成坐标,得到的数值再变坐标。那么实际上当循环出现的时候,嵌套数组的长度也不能再增加了,而出现的这个相同的数一定是嵌套数组的首元素 #1 其实对于遍历过的数字,我们不用再将其当作开头来计算了,而是只对于未遍历过的数字当作嵌套数组的开头数字,不过在进行嵌套运算的时候,并不考虑中间的数字是否已经访问过,而是只要找到和起始位置相同的数字位置,然后更新结果res [Mine]如果相同的数不是嵌套数字的首元素,就说明相同数有两个入度,就说明数组中有相同元素,与题意不符 #2 并不需要专门的数组来记录数组是否被遍历过,而是我们在遍历的过程中,将其交换到其应该出现的位置上,因为如果某个数出现在正确的位置上,那么它一定无法组成嵌套数组,这样就相当于我们标记了其已经访问过了

[LeetCode#469] Convex Polygon 凸多边形 Given a list of points that form a polygon when joined sequentially, find if this polygon is convex (Convex polygon definition). Note: There are at least 3 and at most 10,000 points. Coordinates are in the range -10,000 to 10,000. You may assume the polygon formed by given points is always a simple polygon (Simple polygon definition). In other words, we ensure that exactly two edges intersect at each vertex, and that edges otherwise don't intersect each other. Example 1: [[0,0],[0,1],[1,1],[1,0]] Answer: True Explanation: Example 2: [[0,0],[0,10],[10,10],[10,0],[5,5]] Answer: False Explanation:

凸多边形的性质:所有的顶点角都不大于180度 利用以当前顶点为中心的矢量叉乘或者计算三角形的有符号面积判断多边形的方向以及当前顶点的凹凸性 假设当前连续的三个顶点分别是P1,P2,P3。计算向量P1P2,P2P3的叉乘,也可以计算三角形P1P2P3的面积,得到的结果如果大于0,则表示P3点在线段P1和P2的左侧,多边形的顶点是逆时针序列。然后依次计算下一个前后所组成向量的叉乘,如果在计算时,出现负值,则此多边形时凹多边形,如果所有顶点计算完毕,其结果都是大于0,则多边形时凸多边形。

[LeetCode#505] The Maze II 迷宫之二 There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolling up, down, left or right, but it won't stop rolling until hitting a wall. When the ball stops, it could choose the next direction. Given the ball's start position, the destination and the maze, find the shortest distance for the ball to stop at the destination. The distance is defined by the number of empty spaces traveled by the ball from the start position (excluded) to the destination (included). If the ball cannot stop at the destination, return -1. The maze is represented by a binary 2D array. 1 means the wall and 0 means the empty space. You may assume that the borders of the maze are all walls. The start and destination coordinates are represented by row and column indexes. Example 1 Input 1: a maze represented by a 2D array 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 1 0 0 0 0 0 Input 2: start coordinate (rowStart, colStart) = (0, 4) Input 3: destination coordinate (rowDest, colDest) = (4, 4) Output: 12 Explanation: One shortest way is : left -> down -> left -> down -> right -> down -> right. The total distance is 1 + 1 + 3 + 1 + 2 + 2 + 2 = 12. Example 2 Input 1: a maze represented by a 2D array 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 1 0 0 0 0 0 Input 2: start coordinate (rowStart, colStart) = (0, 4) Input 3: destination coordinate (rowDest, colDest) = (3, 2) Output: -1 Explanation: There is no way for the ball to stop at the destination. Note: There is only one ball and one destination in the maze. Both the ball and the destination exist on an empty space, and they will not be at the same position initially. The given maze does not contain border (like the red rectangle in the example pictures), but you could assume the border of the maze are all walls. The maze contains at least 2 empty spaces, and both the width and height of the maze won't exceed 100.

出到达终点,并停下来,的最少步数 dists[i][j]表示到达(i,j)这个位置时需要的最小步数,我们都初始化为整型最大值,在后在遍历的过程中不断用较小值来更新每个位置的步数值,最后我们来看终点位置的步数值,如果还是整型最大值的话,说明没法在终点处停下来,返回-1,否则就返回步数值。注意在压入栈的时候,我们对x和y进行了判断,只有当其不是终点的时候才压入栈,这样是做了优化,因为如果小球已经滚到终点了,我们就不要让它再滚了,就不把终点位置压入栈,免得它还滚 #1 BFS queue #2 DFS

[LeetCode#561] Array Partition I 数组分割之一 Given an array of 2n integers, your task is to group these integers into n pairs of integer, say (a1, b1), (a2, b2), ..., (an, bn) which makes sum of min(ai, bi) for all i from 1 to n as large as possible. Example 1: Input: [1,4,3,2] Output: 4 Explanation: n is 2, and the maximum sum of pairs is 4. Note: n is a positive integer, which is in the range of [1, 10000]. All the integers in the array will be in the range of [-10000, 10000].

分割数组,两两一对,让每对中较小的数的和最大 给数组排个序,然后按顺序的每两个就是一对,我们取出每对中的第一个数即为较小值累加起来即可

[LeetCode#592] Fraction Addition and Subtraction 分数加减法 Given a string representing an expression of fraction addition and subtraction, you need to return the calculation result in string format. The final result should be irreducible fraction. If your final result is an integer, say 2, you need to change it to the format of fraction that has denominator 1. So in this case, 2 should be converted to 2/1. Example 1: Input:"-1/2+1/2" Output: "0/1" Example 2: Input:"-1/2+1/2+1/3" Output: "1/3" Example 3: Input:"1/3-1/2" Output: "-1/6" Example 4: Input:"5/3+1/3" Output: "2/1" Note: The input string only contains '0' to '9', '/', '+' and '-'. So does the output. Each fraction (input and output) has format ±numerator/denominator. If the first input fraction or the output is positive, then '+' will be omitted. The input only contains valid irreducible fractions, where the numerator and denominator of each fraction will always be in the range [1,10]. If the denominator is 1, it means this fraction is actually an integer in a fraction format defined above. The number of given fractions will be in the range [1,10]. The numerator and denominator of the final result are guaranteed to be valid and in the range of 32-bit int.

分数的加减法,给了我们一个分数加减法式子的字符串,然我们算出结果,结果当然还是用分数表示了 必须将分母变为同一个数,分子才能相加,为了简便,我们不求最小公倍数,而是直接乘上另一个数的分母,然后相加。不过得到的结果需要化简一下,我们求出分子分母的最大公约数,记得要取绝对值,然后分子分母分别除以这个最大公约数就是最后的结果了 [Mine]最大公约数,辗转相除法 int gcd(int a, int b) { return (b == 0) ? a : gcd(b, a % b); }

[LeetCode#551] Student Attendance Record I 学生出勤记录之一 You are given a string representing an attendance record for a student. The record only contains the following three characters: 'A' : Absent. 'L' : Late. 'P' : Present. A student could be rewarded if his attendance record doesn't contain more than one 'A' (absent) or more than two continuous 'L' (late). You need to return whether the student could be rewarded according to his attendance record. Example 1: Input: "PPALLP" Output: True Example 2: Input: "PPALLL" Output: False

判断学生的出勤率是否是优秀,判断标准是不能缺勤两次和不能连续迟到三次 #1 逐个字符变量,计数 #2 字符串搜索 第一个条件是找不到A,或者正着找A和逆着找A在同一个位置(说明只有一个A);第二个条件是找不到LLL,说明不能连续迟到三次 #3 正则式 正则匹配式是A.*A|LLL,其中.*表示有零个或者多个,那么A.*A就是至少有两A的情况,LLL是三个连续的迟到,|表示两个是或的关系,只要能匹配出任意一种情况,就会返回false

[LeetCode#450] Delete Node in a BST 删除二叉搜索树中的节点 Given a root node reference of a BST and a key, delete the node with the given key in the BST. Return the root node reference (possibly updated) of the BST. Basically, the deletion can be divided into two stages: Search for a node to remove. If the node is found, delete the node. Note: Time complexity should be O(height of tree). Example: root = [5,3,6,2,4,null,7] key = 3 5 / \ 3 6 / \ \ 2 4 7 Given key to delete is 3. So we find the node with value 3 and delete it. One valid answer is [5,4,6,2,null,null,7], shown in the following BST. 5 / \ 4 6 / \ 2 7 Another valid answer is [5,2,6,null,4,null,7]. 5 / \ 2 6 \ \ 4 7

利用BST找到要删除的节点 首先判断是否有一个子节点不存在,那么我们就将root指向另一个节点,并返回给父节点(root就删除了) 难点就在于处理左右子节点都存在的情况,我们需要在右子树找到最小值,即右子树中最左下方的节点,然后将该最小值赋值给root,然后再在右子树中调用相同函数(递归)来在右子树(同样是BST)中删除这个值最小的节点

[LeetCode#527] Word Abbreviation 单词缩写 Given an array of n distinct non-empty strings, you need to generate minimal possible abbreviations for every word following rules below. Begin with the first character and then the number of characters abbreviated, which followed by the last character. If there are any conflict, that is more than one words share the same abbreviation, a longer prefix is used instead of only the first character until making the map from word to abbreviation become unique. In other words, a final abbreviation cannot map to more than one original words. If the abbreviation doesn't make the word shorter, then keep it as original. Example: Input: ["like", "god", "internal", "me", "internet", "interval", "intension", "face", "intrusion"] Output: ["l2e","god","internal","me","i6t","interval","inte4n","f2e","intr4n"] Note: Both n and the length of each word will not exceed 400. The length of each word is greater than 1. The words consist of lowercase English letters only. The return answers should be in the same order as the original array.

单词的缩写形式,就是首尾字母加上中间字符的个数组成的新字符串,但是要求是不能有重复的缩写字符串,而且说明如果缩写字符串的长度并没有减小的话就保留原来的字符串 #1 pre数组来记录每个单词缩写形式开头字母的长度,初始化都为1,然后先求出所有单词pre为1的缩写形式,对比缩写字符串进行冲突处理。把冲突字符串的坐标存入冲突集合中,然后遍历冲突集合中所有的位置,pre对应的值自增1,对其调用缩写函数,再次对比缩写字符串,记录冲突集合,直到冲突集合为空为止。 [Mine]每一个字符串的不同长度前缀缩写,寻找是否有冲突。有冲突就增加前缀长度。不断推进各个字符串的前缀长度,直至互相都无冲突 1。如果A和B在前缀为1时的缩写没有冲突,那么A换成前缀为2时也一定和B无冲突

[LeetCode#471] Encode String with Shortest Length 最短长度编码字符串 Given a non-empty string, encode the string such that its encoded length is the shortest. The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated exactly k times. Note: k will be a positive integer and encoded string will not be empty or have extra space. You may assume that the input string contains only lowercase English letters. The string's length is at most 160. If an encoding process does not make the string shorter, then do not encode it. If there are several solutions, return any of them is fine. Example 1: Input: "aaa" Output: "aaa" Explanation: There is no way to encode it such that it is shorter than the input string, so we do not encode it. Example 2: Input: "aaaaa" Output: "5[a]" Explanation: "5[a]" is shorter than "aaaaa" by 1 character. Example 3: Input: "aaaaaaaaaa" Output: "10[a]" Explanation: "a9[a]" or "9[a]a" are also valid solutions, both of them have the same length = 5, which is the same as "10[a]". Example 4: Input: "aabcaabcd" Output: "2[aabc]d" Explanation: "aabc" occurs twice, so one answer can be "2[aabc]d". Example 5: Input: "abbbabbbcabbbabbbc" Output: "2[2[abbb]c]" Explanation: "abbbabbbc" occurs twice, but "abbbabbbc" can also be encoded to "2[abbb]c", so one answer can be "2[2[abbb]c]".

压缩字符串,把相同的字符串用中括号括起来,然后在前面加上出现的次数 二维的DP数组,其中dp[i][j]表示s在[i, j]范围内的字符串的缩写形式(如果缩写形式长度大于子字符串,那么还是保留子字符串,初始化为[i, j]范围内的字符串) 对于任意一段子字符串[i, j],我们我们以中间任意位置k来拆分成两段,比较dp[i][k]加上dp[k+1][j]的总长度和dp[i][j]的长度,将长度较小的字符串赋给dp[i][j] [Mine]知道各个子串的缩写形式,用不同分割方法,合并组成成更大子串的缩写形式。 关键是找sub = abcabc这种可压缩的情况,其中sub = s[i,j]。 巧妙方法:用sub+sub = abcabcabcabc,找第二个s在s+s里出现的位置,如果不是len(sub),则说明sub有重复,那么就要压缩这个sub,重复次数是len(sub) / indexOf(sub, 1)。 这里第二个s在s+s里出现的位置是3,不是len(sub)=6,说明重复次数是len(sub) / indexOf(sub, 1)=2 [Mine]无法判断准确的重复子串开始和结束时,只能遍历每个子串。 没有记录大子串中是否有小子串被重复子串压缩过,生成大子串压缩时,只能比较各种分割可能的小子串压缩长度和。

[LeetCode#416] Partition Equal Subset Sum 相同子集和分割 Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal. Note: Both the array size and each of the array element will not exceed 100. Example 1: Input: [1, 5, 11, 5] Output: true Explanation: The array can be partitioned as [1, 5, 5] and [11]. Example 2: Input: [1, 2, 3, 5] Output: false Explanation: The array cannot be partitioned into equal sum subsets.

原数组所有数字和一定是偶数,不然根本无法拆成两个和相同的子集合,那么我们只需要算出原数组的数字之和,然后除以2,就是我们的target #1 dp数组,其中dp[i]表示数字i是否是原数组的任意个子集合之和,那么我们我们最后只需要返回dp[target]就行了 对于遍历到的每个数字nums[i],我们需要更新我们的dp数组,要更新[nums[i], target]之间的值,那么对于这个区间中的任意一个数字j, dp[j] = dp[j] || dp[j - nums[i]] (nums[i] <= j <= target) [Mine]递归应该也可以找到一个集合,其sum为target #2 bisets的大小设为5001 因为题目中说了数组的长度和每个数字的大小都不会超过100,那么最大的和为10000,那么一半就是5000,前面再加上个0,就是5001了 遍历数字,对于遍历到的数字num,我们把bits向左平移num位,然后再或上原来的bits,这样所有的可能出现的和位置上都为1 最后去看bits[sum >> 1]是否为1即可 for (int num : nums) bits |= bits << num; return (sum % 2 == 0) && bits[sum >> 1]; [Mine]每个bit代表一种sum的可能,比如bit[5]代表sum可以等于5。那么bits |= bits << num,代表前面所有可能的sum与num相加,加上之前的sum的合集,即num加入后的所有可能sum。"前面所有可能的sum与num相加"在#2中就是左移,增加之前可能距离bit[0]的距离。 [Mine]一定不要想着了的bit是num的二进制,错。这里的bit[i]是可能的sum=i,一种距离bit[0]的距离

[LeetCode#594] Longest Harmonious Subsequence 最长和谐子序列 We define a harmonious array is an array where the difference between its maximum value and its minimum value is exactly 1. Now, given an integer array, you need to find the length of its longest harmonious subsequence among all its possible subsequences. Example 1: Input: [1,3,2,2,5,2,3,7] Output: 5 Explanation: The longest harmonious subsequence is [3,2,2,2,3]. Note: The length of the input array will not exceed 20,000.

和谐子序列就是序列中数组的最大最小差值均为1 #1 对数组进行排序,那么实际上我们只要找出来相差为1的两个数的总共出现个数就是一个和谐子序列的长度了。 建立一个数字和其出现次数之间的映射,利用map的自动排序的特性,那么我们遍历map的时候就是从小往大开始遍历,我们从第二个映射对开始遍历,每次跟其前面的映射对比较,如果二者的数字刚好差1,那么就把二个数字的出现的次数相加并更新结果res即可 #2 不用排序,遍历每个数字的时候,只需在map中查找该数字加1是否存在,存在就更新结果res

[LeetCode#465] Optimal Account Balancing 最优账户平衡 A group of friends went on holiday and sometimes lent each other money. For example, Alice paid for Bill's lunch for 10.ThenlaterChrisgaveAlice 5 for a taxi ride. We can model each transaction as a tuple (x, y, z) which means person x gave person y $z. Assuming Alice, Bill, and Chris are person 0, 1, and 2 respectively (0, 1, 2 are the person's ID), the transactions can be represented as [[0, 1, 10], [2, 0, 5]]. Given a list of transactions between a group of people, return the minimum number of transactions required to settle the debt. Note: A transaction will be given as a tuple (x, y, z). Note that x ≠ y and z > 0. Person's IDs may not be linear, e.g. we could have the persons 0, 1, 2 or we could also have the persons 0, 2, 6. Example 1: Input: [[0,1,10], [2,0,5]] Output: 2 Explanation: Person #0 gave person #1 $10. Person #2 gave person #0 $5. Two transactions are needed. One way to settle the debt is person #1 pays person #0 and #2 $5 each. Example 2: Input: [[0,1,10], [1,0,1], [1,2,5], [2,0,5]] Output: 1 Explanation: Person #0 gave person #1 $10. Person #1 gave person #0 $1. Person #1 gave person #2 $5. Person #2 gave person #0 $5. Therefore, person #1 only need to give person #0 $4, and all debt is settled.

哈希表来建立每个人和其账户的映射,其中账户若为正数,说明其他人欠你钱;如果账户为负数,说明你欠别人钱 递归: 遍历,递归选择正负两个账户,将index小的账户债务消减掉。如果本来正负不等额,会造成后面那个账户的正负变化。每次平一个帐号,知道所有账户都平了。记录步数最少方案

[LeetCode#522] Longest Uncommon Subsequence II 最长非共同子序列之二 Given a list of strings, you need to find the longest uncommon subsequence among them. The longest uncommon subsequence is defined as the longest subsequence of one of these strings and this subsequence should not be any subsequence of the other strings. A subsequence is a sequence that can be derived from one sequence by deleting some characters without changing the order of the remaining elements. Trivially, any string is a subsequence of itself and an empty string is a subsequence of any string. The input will be a list of strings, and the output needs to be the length of the longest uncommon subsequence. If the longest uncommon subsequence doesn't exist, return -1. Example 1: Input: "aba", "cdc", "eae" Output: 3 Note: All the given strings' lengths will not exceed 10. The length of the given list will be in the range of [2, 50].

多个字符串 #1 暴力搜索 遍历所有的字符串,对于每个遍历到的字符串,再和所有的其他的字符串比较,看是不是某一个字符串的子序列,如果都不是的话,那么当前字符串就是一个非共同子序列,用其长度来更新结果res #2 优化 1.给字符串按长度来排序,将长度大的放到前面 2.利用集合的去重复特性,这样在有大量的重复字符串的时候可以提高效率

[LeetCode#521] Longest Uncommon Subsequence I 最长非共同子序列之一 Given a group of two strings, you need to find the longest uncommon subsequence of this group of two strings. The longest uncommon subsequence is defined as the longest subsequence of one of these strings and this subsequence should not be any subsequence of the other strings. A subsequence is a sequence that can be derived from one sequence by deleting some characters without changing the order of the remaining elements. Trivially, any string is a subsequence of itself and an empty string is a subsequence of any string. The input will be two strings, and the output needs to be the length of the longest uncommon subsequence. If the longest uncommon subsequence doesn't exist, return -1. Example 1: Input: "aba", "cdc" Output: 3 Explanation: The longest uncommon subsequence is "aba" (or "cdc"), because "aba" is a subsequence of "aba", but not a subsequence of any other strings in the group of two strings. Note: Both strings' lengths will not exceed 100. Only letters from a ~ z will appear in input strings.

如果两个字符串相等,那么一定没有非共同子序列,反之,如果两个字符串不等,那么较长的那个字符串就是最长非共同子序列

[LeetCode#440] K-th Smallest in Lexicographical Order 字典顺序的第K小数字 Given integers n and k, find the lexicographically k-th smallest integer in the range from 1 to n. Note: 1 ≤ k ≤ n ≤ 109. Example: Input: n: 13 k: 2 Output: 10 Explanation: The lexicographical order is [1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9], so the second smallest number is 10.

如果仔细观察字典顺序的数组,我们可以发现,其实这是个十叉树Denary Tree,就是每个节点的子节点可以有十个,但是由于n大小的限制,构成的并不是一个满十叉树。 难点就变成了如何计算出每个节点的子节点的个数,我们不停的用k减去子节点的个数,当k减到0的时候,当前位置的数字即为所求。 首先把1本身这一个数字加到step中,然后我们把范围扩大十倍,范围变成10到20之前,但是由于我们要考虑n的大小,由于n为13,所以只有4个子节点,这样我们就知道从数字1遍历到数字2需要经过5个数字,然后我们看step是否小于等于k,如果是,我们cur自增1,k减去step;如果不是,说明要求的数字在子节点中,我们此时cur乘以10,k自减1[Mine: 跳过了数字1],以此类推,直到k为0推出循环,此时cur即为所求 first = cur, last = cur + 1; while (first <= n) { step += min((long long)n + 1, last) - first; first *= 10; last *= 10; } [Mine]step等于cur下的十叉树的节点数。查找kth跨过了几棵树

[LeetCode#483] Smallest Good Base 最小的好基数 For an integer n, we call k>=2 a good base of n, if all digits of n base k are 1. Now given a string representing n, you should return the smallest good base of n in string format. Example 1: Input: "13" Output: "3" Explanation: 13 base 3 is 111. Example 2: Input: "4681" Output: "8" Explanation: 4681 base 8 is 11111. Example 3: Input: "1000000000000000000" Output: "999999999999999999" Explanation: 1000000000000000000 base 999999999999999999 is 11. Note: The range of n is [3, 10^18]. The string representing n is always valid and will not have leading zeros.

如果我们用k表示基数,m表示转为全1数字的位数,那么数字n就可以拆分为: n = 1 + k + k^2 + k^3 + ... + k^(m-1) m的下限为2,m最大,那么k就要最小,k最小是2,那么m最大只能为log(n + 1)/log2 since n > k^(m-1), k < n^(1 / (m-1)), k的下限为2 m从上限向下限扫描,用二分法找可能符合要求的k [Mine]感觉这种题都是用数学公式,计算出上下限,然后二分查找。

[LeetCode#474] Ones and Zeroes 一和零 In the computer world, use restricted resource you have to generate maximum benefit is what we always want to pursue. For now, suppose you are a dominator of m 0s and n 1s respectively. On the other hand, there is an array with strings consisting of only 0s and 1s. Now your task is to find the maximum number of strings that you can form with given m 0s and n 1s. Each 0 and 1 can be used at most once. Note: The given numbers of 0s and 1s will both not exceed 100 The size of given string array won't exceed 600. Example 1: Input: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3 Output: 4 Explanation: This are totally 4 strings can be formed by the using of 5 0s and 3 1s, which are "10,"0001","1","0" Example 2: Input: Array = {"10", "0", "1"}, m = 1, n = 1 Output: 2 Explanation: You could form "10", but then you'd have nothing left. Better form "0" and "1".

如果我们看到这种求总数,而不是列出所有情况的题,十有八九都是用DP来解 dp[i][j]表示有i个0和j个1时能组成的最多字符串的个数,而对于当前遍历到的字符串,我们统计出其中0和1的个数为zeros和ones dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1); similar to #322 Coin Change

[LeetCode414] Third Maximum Number 第三大的数 Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n). Example 1: Input: [3, 2, 1] Output: 1 Explanation: The third maximum is 1. Example 2: Input: [1, 2] Output: 2 Explanation: The third maximum does not exist, so the maximum (2) is returned instead. Example 3: Input: [2, 2, 3, 1] Output: 1 Explanation: Note that the third maximum here means the third maximum distinct number. Both numbers with value 2 are both considered as second maximum.

如果知道怎么求第二大的数,那么求第三大的数的思路都是一样的。那么我们用三个变量first, second, third来分别保存第一大,第二大,和第三大的数

[LeetCode#508] Most Frequent Subtree Sum 出现频率最高的子树和 Given the root of a tree, you are asked to find the most frequent subtree sum. The subtree sum of a node is defined as the sum of all the node values formed by the subtree rooted at that node (including the node itself). So what is the most frequent subtree sum value? If there is a tie, return all the values with the highest frequency in any order. Examples 1 Input: 5 / \ 2 -3 return [2, -3, 4], since all the values happen only once, return all of them in any order. Examples 2 Input: 5 / \ 2 -5 return [2], since 2 happens twice, however -5 only occur once. Note: You may assume the sum of values in any subtree is in the range of 32-bit signed integer.

子树是从下往上构建的,这种特点很适合使用后序遍历 cnt来记录当前最多的次数,hashmap记录sum和次数对

[LeetCode#408] Valid Word Abbreviation 验证单词缩写 Given a non-empty string s and an abbreviation abbr, return whether the string matches with the given abbreviation. A string such as "word" contains only the following valid abbreviations: ["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"] Notice that only the above abbreviations are valid abbreviations of the string "word". Any other string is not a valid abbreviation of "word". Note: Assume s contains only lowercase letters and abbr contains only lowercase letters and digits. Example 1: Given s = "internationalization", abbr = "i12iz4n": Return true. Example 2: Given s = "apple", abbr = "a2e": Return false.

字母直接对比 数字,取完整有效数字,对比指针移动

[LeetCode#526] Beautiful Arrangement 优美排列 Suppose you have N integers from 1 to N. We define a beautiful arrangement as an array that is constructed by these N numbers successfully if one of the following is true for the ith position (1 ≤ i ≤ N) in this array: The number at the ith position is divisible by i. i is divisible by the number at the ith position. Now given N, how many beautiful arrangements can you construct? Example 1: Input: 2 Output: 2 Explanation: The first beautiful arrangement is [1, 2]: Number at the 1st position (i=1) is 1, and 1 is divisible by i (i=1). Number at the 2nd position (i=2) is 2, and 2 is divisible by i (i=2). The second beautiful arrangement is [2, 1]: Number at the 1st position (i=1) is 2, and 2 is divisible by i (i=1). Number at the 2nd position (i=2) is 1, and i (i=2) is divisible by 1. Note: N is a positive integer and will not exceed 15.

对于该排列中的所有数,如果数字可以整除下标,或者下标可以整除数字,那么我们就是优美排列,让我们求出所有优美排列的个数。 全排列中筛出符合条件的排列 #1 DFS + visited #2 DFS + swap

[LeetCode#466] Count The Repetitions 计数重复个数 Define S = [s,n] as the string S which consists of n connected strings s. For example, ["abc", 3] ="abcabcabc". On the other hand, we define that string s1 can be obtained from string s2 if we can remove some characters from s2 such that it becomes s1. For example, "abc" can be obtained from "abdbec" based on our definition, but it can not be obtained from "acbbe". You are given two non-empty strings s1 and s2 (each at most 100 characters long) and two integers 0 ≤ n1 ≤ 106and 1 ≤ n2 ≤ 106. Now consider the strings S1 and S2, where S1=[s1,n1] and S2=[s2,n2]. Find the maximum integer M such that [S2,M] can be obtained from S1. Example: Input: s1="acb", n1=4 s2="ab", n2=2 Return: 2

寻找循环节。找到s2在S1中的循环节 我们遍历s1字符串n1次,表示每个s1字符串为一段,对于每段,我们有: 1. 出现在该段的s2字符串的累计出现次数[repeatCount] 2. 一个nextIndex,其中s2[nextIndex]表示在下一段s1中你所要寻找的第一个字符。(比如说s1="abc", s2="bac", 由于要寻找s2的第一个字符b,而b在s1中的位置是1,所以nextIndex=1;同理,比如s1="abca", s2="bac",那么nextIndex=2) [Mine]nextIndex记录每进入一段新s1时,要找的s2的nextIndex,一旦和之前某段s1的nextIndex相同,说明循环节开始,然后根据repeatCount,在此段及其之前所有s1找到的s2总数,计算出 repeatCnt[i]到第i个s1结束时,包含s2数目 interval:两个相同nextIndex的repeatCount之差 repeat :仅循环节(不包括第一个循环节前,和最后一个循环节后)在n1个s1中的循环节数量 patternCnt :repeatCnt[cur]-repeatCnt[start],times repeat remainCnt :假设刨去中间所有循环节,第一个循环节前加上最后一个循环节后,包含的s1数量repeatCnt[start + (n1 - start) % interval]; if 有循环节 return (patternCnt + remainCnt) / n2; else return repeatCnt[n1] / n2; [Mine]不好想到的 1.用nextIndex来确定循环节 2.remainCnt = repeatCnt[start + (n1 - start) % interval];

[LeetCode#514] Freedom Trail 自由之路 In the video game Fallout 4, the quest "Road to Freedom" requires players to reach a metal dial called the "Freedom Trail Ring", and use the dial to spell a specific keyword in order to open the door. Given a string ring, which represents the code engraved on the outer ring and another string key, which represents the keyword needs to be spelled. You need to find the minimum number of steps in order to spell all the characters in the keyword. Initially, the first character of the ring is aligned at 12:00 direction. You need to spell all the characters in the string key one by one by rotating the ring clockwise or anticlockwise to make each character of the string key aligned at 12:00 direction and then by pressing the center button. At the stage of rotating the ring to spell the key character key[i]: You can rotate the ring clockwise or anticlockwise one place, which counts as 1 step. The final purpose of the rotation is to align one of the string ring's characters at the 12:00 direction, where this character must equal to the character key[i]. If the character key[i] has been aligned at the 12:00 direction, you need to press the center button to spell, which also counts as 1 step. After the pressing, you could begin to spell the next character in the key (next stage), otherwise, you've finished all the spelling. Example: Input: ring = "godding", key = "gd" Output: 4 Explanation: For the first key character 'g', since it is already in place, we just need 1 step to spell this character. For the second key character 'd', we need to rotate the ring "godding" anticlockwise by two steps to make it become "ddinggo". Also, we need 1 more step for spelling. So the final output is 4. Note: Length of both ring and key will be in range 1 to 100. There are only lowercase letters in both strings and might be some duplcate characters in both strings. It's guaranteed that string key could always be spelled by rotating the string ring.

将密码字符串都转出来,让我们求最短的转动步数。 #1 DP dp[i][j]表示转动从i位置开始的key串所需要的最少步数(这里不包括spell的步数,因为spell可以在最后统一加上),此时表盘的12点位置是ring中的第j个字符。可以从key的末尾往前推,这样dp[0][0]就是我们所需要的结果 dp[i][j] = min(dp[i][j], step + dp[i + 1][k]); step是12点位置是ring中的第j个字符时,拨到一个key[i]位置所需要的step。k为拨到这个key[i]位置时 表盘的12点位置是ring中的第k个字符,且ring[k] == key[i] [Mine] dp[i][j] = min(dp[i][j], step + dp[i + 1][k]); ring[k] == key[i]; 意思是12位置是ring[j],目标是key[i]时到最终状态的最少步数为,12位置是ring[k] =key[i],即12点转到了key[i]之后 ,目标是key[i+1]时到最终状态的最少步数+12点位置ring[j]转到ring[k]的最少步数。 #DFS + memory memo[x][y],x为当前12点在ring中的offset,y为key中的目标字符。 需要一个hashmap(或v[26][])来记录每个字母在ring中的出现位置。对每个目标字符,ring上有多个位置,每个位置有正转,反转两个走法。 相同位置正转反转,肯定选step最短的。多个可选位置,就要DPS分别搜索。 [Mine]DFS + memory应该是最好想到的方法。 [Mine]DP是DFS+Memory的迭代写法:由于最后状态是确定的,我们要从最后向前推。把之前各种可能状态(遍历12点位置是ring上各个字符的状态)变到最终态的最佳解都计算出来。所以DP要显示出目标i,在key中的index,和,当前状态j,12点字符在ring中的index。 最后,挑选i=0, j=0的最佳解。 最初状态向后推,或最后状态向前推,都无法用贪婪算法。 [Mine]作者说这是顺序重现关系的例子,那么顺序重现关系可以理解为试图给出DFS+Memory的迭代写法的倒推过程:T(i, j) = T(i, j - 1) + C

[LeetCode#486] Predict the Winner 预测赢家 Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from either end of the array followed by the player 2 and then player 1 and so on. Each time a player picks a number, that number will not be available for the next player. This continues until all the scores have been chosen. The player with the maximum score wins. Given an array of scores, predict whether player 1 is the winner. You can assume each player plays to maximize his score. Example 1: Input: [1, 5, 2] Output: False Explanation: Initially, player 1 can choose between 1 and 2. If he chooses 2 (or 1), then player 2 can choose from 1 (or 2) and 5. If player 2 chooses 5, then player 1 will be left with 1 (or 2). So, final score of player 1 is 1 + 2 = 3, and player 2 is 5. Hence, player 1 will never be the winner and you need to return False. Example 2: Input: [1, 5, 233, 7] Output: True Explanation: Player 1 first chooses 1. Then player 2 have to choose between 5 and 7. No matter which number player 2 choose, player 1 can choose 233. Finally, player 1 has more score (234) than player 2 (12), so you need to return True representing player1 can win. Note: 1 <= length of the array <= 20. Any scores in the given array are non-negative integers and will not exceed 10,000,000. If the scores of both players are equal, then player 1 is still the winner.

当前玩家赢返回true的条件就是递归调用下一个玩家输返回false #1 递归 如果数组有多个数字,我们分别生成两个新数组,一个是去掉首元素,一个是去掉尾元素,然后根据玩家标识分别调用不同的递归,只要下一个玩家两种情况中任意一种返回false了,那么当前玩家就可以赢了 #2 递归 Minimax的方法 + Memory dp[i][j]为遇到区间[i,j]数字的player能比对手多拿的score,所以ret=dp[0][n-1] > 0 int canWin(vector<int>& nums, int s, int e, vector<vector<int>>& dp) { if (dp[s][e] == -1) { dp[s][e] = (s == e) ? nums[s] : max(nums[s] - canWin(nums, s + 1, e, dp), nums[e] - canWin(nums, s, e - 1, dp)); } return dp[s][e]; } #3 DP dp[i][j] same meaning as #2 for (int i = 0; i < n; ++i) dp[i][i] = nums[i]; for (int len = 1; len < n; ++len) { for (int i = 0, j = len; j < n; ++i, ++j) { dp[i][j] = max(nums[i] - dp[i + 1][j], nums[j] - dp[i][j - 1]); } } return dp[0][n - 1] >= 0; [Mine]结果depend on中间任何区间的结果,大区间结果depend on小区间结果。 由小到大算出任意区间结果,就能拼出最终结果。

[LeetCode#453] Minimum Moves to Equal Array Elements 最少移动次数使数组元素相等 Given a non-empty integer array of size n, find the minimum number of moves required to make all array elements equal, where a move is incrementing n - 1 elements by 1. Example: Input: [1,2,3] Output: 3 Explanation: Only three moves are needed (remember each move increments two elements): [1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]

我们每次可以对n-1个数字同时加1,问最少需要多少次这样的操作才能让数组中所有的数字相等。 需要换一个角度来看问题,其实给n-1个数字加1,效果等同于给那个未被选中的数字减1 #1 只要先找到最小值,然后累加每个数跟最小值之间的差值即可 #2 也可以求出数组的数字之和sum,然后用sum减去最小值和数组长度的乘积

[LeetCode#552] Student Attendance Record II 学生出勤记录之二 Given a positive integer n, return the number of all possible attendance records with length n, which will be regarded as rewardable. The answer may be very large, return it after mod 109 + 7. A student attendance record is a string that only contains the following three characters: 'A' : Absent. 'L' : Late. 'P' : Present. A record is regarded as rewardable if it doesn't contain more than one 'A' (absent) or more than two continuous 'L' (late). Example 1: Input: n = 2 Output: 8 Explanation: There are 8 records with length 2 will be regarded as rewardable: "PP" , "AP", "PA", "LP", "PL", "AL", "LA", "LL" Only "AA" won't be regarded as rewardable owing to more than one absent times. Note: The value of n won't exceed 100,000.

所有符合rewardable的数量 从题目中说结果要对一个很大的数取余,说明结果是一个很大很大的数。那么一般来说这种情况不能用递归来求解,可能会爆栈,所以要考虑利用数学方法或者DP来做。 #1 三维的dp数组,其中dp[i][j][k] 表示数组前i个数字中,最多有j个A,最多有k个连续L的组合方式,那么我们最终要求的结果就保存在dp[n][1][2]中 [Mine]??????? #2 三个DP数组P, L, A,其中P[i]表示数组[0,i]范围内以P结尾的所有排列方式,L[i]表示数组[0,i]范围内以L结尾的所有排列方式,A[i]表示数组[0,i]范围内以A结尾的所有排列方式。 P[i] = A[i-1] + P[i-1] + L[i-1] L[i] = A[i-1] + P[i-1] + A[i-2] + P[i-2] 实际上我们还需要定义两个数组P1, L1, 其中P1[i]表示数组[0,i]范围内以P结尾的不包含A的所有排列方式,L1[i]表示数组[0,i]范围内以L结尾的不包含A的所有排列方式, A[i] = P1[i-1] + L1[i-1] P1[i] = P1[i-1] + L1[i-1] L1[i] = P1[i-1] + P1[i-2] so, A[i] = A[i-1] + A[i-2] + A[i-3] [Mine] A[i-1]其实是等于A[i]中结尾是PA的case A[i-2]其实是等于A[i]中结尾是PLA的case A[i-3]其实是等于A[i]中结尾是PLLA的case 这样就覆盖了所有合法case #3 两个数组P和PorL,其中P[i]表示数组前i个数字中已P结尾的排列个数,PorL[i]表示数组前i个数字中已P或者L结尾的排列个数 P[i] = PorL[i-1] L[i]只能当前一个字符是P,或者前一个字符是L且再前一个字符是P的时候加上,即为P[i-1] + P[i-2],所以PorL[i] = P[i] + P[i-1] + P[i-2] 相当于在数组的任意一个位置上加上A,那么数组就被分成左右两个部分了,而这两个部分当然就不能再有A了 两个子数组的排列个数相乘,然后再把所有分割的情况累加起来就是最终结果啦, [Mine]#3最好理解,把A的情况先分出来,利用P[i] and PorL[i]的递推式确保没有连续三个L

[LeetCode#457] Circular Array Loop 环形数组循环 You are given an array of positive and negative integers. If a number n at an index is positive, then move forward n steps. Conversely, if it's negative (-n), move backward n steps. Assume the first element of the array is forward next to the last element, and the last element is backward next to the first element. Determine if there is a loop in this array. A loop starts and ends at a particular index with more than 1 element along the loop. The loop must be "forward" or "backward'. Example 1: Given the array [2, -1, 1, 2, 2], there is a loop, from index 0 -> 2 -> 3 -> 0. Example 2: Given the array [-1, 2], there is no loop. Note: The given array is guaranteed to contain no element "0". Can you do it in O(n) time complexity and O(1) space complexity?

所谓的循环必须是一个方向的就是说不能跳到一个数,再反方向跳回来,这不算一个loop。比如[1, -1]就不是一个loop,而[1, 1]是一个正确的loop。 需要一个visited数组,来记录访问过的数字,然后我们遍历原数组,如果当前数字已经访问过了,直接跳过,否则就以当前位置坐标为起始点开始查找,进行while循环,将当前位置在visited数组中标记true,然后计算下一个位置,计算方法是当前位置坐标加上对应的数字 取余或补n,计算位置 如果next和cur相等,说明此时是一个数字的循环,不符合题意,再有就是检查二者的方向,数字是正数表示forward,若是负数表示backward,在一个loop中必须同正或同负,我们只要让二者相乘,如果结果是负数的话,说明方向不同,直接break掉。 [Mine]The loop must be "forward" or "backward'.所以必须"同正同负",这个不行: [2,2,-1,1] 0->2->1->3->0

[LeetCode#548] Split Array with Equal Sum 分割数组成和相同的子数组 Given an array with n integers, you need to find if there are triplets (i, j, k) which satisfies following conditions: 0 < i, i + 1 < j, j + 1 < k < n - 1 Sum of subarrays (0, i - 1), (i + 1, j - 1), (j + 1, k - 1) and (k + 1, n - 1) should be equal. where we define that subarray (L, R) represents a slice of the original array starting from the element indexed L to the element indexed R. Example: Input: [1,2,1,2,1,2,1] Output: True Explanation: i = 1, j = 3, k = 5. sum(0, i - 1) = sum(0, 0) = 1 sum(i + 1, j - 1) = sum(2, 2) = 1 sum(j + 1, k - 1) = sum(4, 4) = 1 sum(k + 1, n - 1) = sum(6, 6) = 1 Note: 1 <= n <= 2000. Elements in the given array will be in range [-1,000,000, 1,000,000].

找出三个位置,使得数组被分为四段,使得每段之和相等,问存不存在这样的三个位置,注意三个位置上的数字不属于任何一段 #1 遍历+循环优化+累加和 1. 先搜索j的位置,那么i和k的位置就可以固定在一个小的范围内了,而且可以在j的循环里面同时进行,这样就少嵌套了一个循环,所以时间复杂度会降一维度。 2. 确定j的范围应该左右各留3个数字,因为四段均不能为空,而且分割位上的数字不能算入四段。 3. 确定了j的位置后,i和k的位置就能分别确定了,我们要做的是先遍历i的所有可能位置,然后遍历所有的拆分情况,如果拆出的两段和相等,则把这个相等的值加入一个集合中,然后再遍历k的所有情况 [Mine]优先确定j,来降低复杂度 #2 递归 [Mine]确定第一段和target,寻找后三段 helper(vector<int>& nums, int target, int sum, int start, int cnt) #3 迭代 (同#2 思想)

[LeetCode#537] Complex Number Multiplication 复数相乘 Given two strings representing two complex numbers. You need to return a string representing their multiplication. Note i2 = -1 according to the definition. Example 1: Input: "1+1i", "1+1i" Output: "0+2i" Explanation: (1 + i) * (1 + i) = 1 + i 2 + 2 * i = 2i, and you need convert it to the form of 0+2i. Example 2: Input: "1+-1i", "1+-1i" Output: "0+-2i" Explanation: (1 - i) * (1 - i) = 1 + i 2 - 2 * i = -2i, and you need convert it to the form of 0+-2i. Note: The input strings will not have extra blank. The input strings will be given in the form of a+bi, where the integer a and b will both belong to the range of [-100, 100]. And the output should be also in this form.

把字符串中的实部和虚部分离开并进行运算 int r1 = a1 * b1 - a2 * b2, r2 = a1 * b2 + a2 * b1; return to_string(r1) + "+" + to_string(r2) + "i";

[LeetCode#538] Convert BST to Greater Tree 将二叉搜索树BST转为较大树 Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST. Example: Input: The root of a Binary Search Tree like this: 5 / \ 2 13 Output: The root of a Greater Tree like this: 18 / \ 20 13

把每个结点值加上所有比它大的结点值总和当作新的结点值。 original 想法:先求出所有结点值之和,然后开始中序遍历数组,同时用变量sum来记录累加和,根据上面分析的规律来更新所有的数组。 smart one:逆中序遍历:将中序遍历左根右的顺序逆过来,变成右根左的顺序,这样就可以反向计算累加和sum,同时更新结点值 逆中序遍历,递归 逆中序遍历,迭代

[LeetCode#500] Keyboard Row 键盘行 Given a List of words, return the words that can be typed using letters of alphabet on only one row's of American keyboard like the image below. American keyboard Example 1: Input: ["Hello", "Alaska", "Dad", "Peace"] Output: ["Alaska", "Dad"] Note: You may use one character in the keyboard more than once. You may assume the input string will only contain letters of alphabet.

把键盘的三行字符分别保存到三个set中,然后遍历每个单词中的每个字符,分别看当前字符是否在三个集合中,如果在,对应的标识变量变为1,我们统计三个标识变量之和就知道有几个集合参与其中了

[LeetCode] 470. Implement Rand10() Using Rand7() 使用Rand7()来实现Rand10() Given a function rand7 which generates a uniform random integer in the range 1 to 7, write a function rand10 which generates a uniform random integer in the range 1 to 10. Do NOT use system's Math.random(). Example 1: Input: 1 Output: [7] Example 2: Input: 2 Output: [8,4] Example 3: Input: 3 Output: [8,1,10] Note: rand7 is predefined. Each testcase has one argument: n, the number of times that rand10 is called. Follow up: What is the expected value for the number of calls to rand7() function? Could you minimize the number of calls to rand7()?

拒绝采样 Rejection Sampling

[LeetCode#421] Maximum XOR of Two Numbers in an Array 数组中异或值最大的两个数字 Given a non-empty array of numbers, a0, a1, a2, ... , an-1, where 0 ≤ ai < 231. Find the maximum result of ai XOR aj, where 0 ≤ i, j < n. Could you do this in O(n) runtime? Example: Input: [3, 10, 5, 25, 2, 8] Output: 28 Explanation: The maximum result is 5 ^ 25 = 28.

按位遍历,按位猜并验证 若a^b=c,那么a=b^c,因为t是我们要验证的当前最大值,所以我们遍历set中的数时,和t异或后的结果仍在set中,说明两个前缀可以异或出t的值,所以我们更新res为t,继续遍历 [Mine]利用若a^b=c,那么a=b^c,从高位到低位猜结果:猜前缀为t,将array所有数的前缀放入set,如同前缀A=前缀B^t,就说明t=前缀A^前缀B,前缀t猜想正确。

[LeetCode#539] Minimum Time Difference 最短时间差 Given a list of 24-hour clock time points in "Hour:Minutes" format, find the minimum minutes difference between any two time points in the list. Example 1: Input: ["23:59","00:00"] Output: 1 Note: The number of time points in the given list is at least 2 and won't exceed 20000. The input time is legal and ranges from 00:00 to 23:59.

无序的时间点,让我们求最短的两个时间点之间的差值。 #1 排序 唯一的特殊情况就是第一个和末尾的时间点进行比较,第一个时间点需要加上24小时再做差值 #2 O(n)时间复杂度的方法,由于时间点并不是无穷多个,而是只有1440个,所以我们建立一个大小为1440的数组来标记某个时间点是否出现过。 [Mine]1440=24*60,其实是自然数,基数排序

[LeetCode#541] Reverse String II 翻转字符串之二 Given a string and an integer k, you need to reverse the first k characters for every 2k characters counting from the start of the string. If there are less than k characters left, reverse all of them. If there are less than 2k but greater than or equal to k characters, then reverse the first k characters and left the other as original. Example: Input: s = "abcdefg", k = 2 Output: "bacdfeg" Restrictions: The string consists of lower English letters only. Length of the given string and k will in the range [1, 10000]

是每隔k隔字符,翻转k个字符,最后如果不够k个了的话,剩几个就翻转几个

[LeetCode#544] Output Contest Matches 输出比赛匹配对 During the NBA playoffs, we always arrange the rather strong team to play with the rather weak team, like make the rank 1 team play with the rank nth team, which is a good strategy to make the contest more interesting. Now, you're given n teams, you need to output their final contest matches in the form of a string. The n teams are given in the form of positive integers from 1 to n, which represents their initial rank. (Rank 1 is the strongest team and Rank n is the weakest team.) We'll use parentheses('(', ')') and commas(',') to represent the contest team pairing - parentheses('(' , ')') for pairing and commas(',') for partition. During the pairing process in each round, you always need to follow the strategy of making the rather strong one pair with the rather weak one. Example 1: Input: 2 Output: (1,2) Explanation: Initially, we have the team 1 and the team 2, placed like: 1,2. Then we pair the team (1,2) together with '(', ')' and ',', which is the final answer. Example 2: Input: 4 Output: ((1,4),(2,3)) Explanation: In the first round, we pair the team 1 and 4, the team 2 and 3 together, as we need to make the strong team and weak team together. And we got (1,4),(2,3). In the second round, the winners of (1,4) and (2,3) need to play again to generate the final winner, so you need to add the paratheses outside them. And we got the final answer ((1,4),(2,3)). Example 3: Input: 8 Output: (((1,8),(4,5)),((2,7),(3,6))) Explanation: First round: (1,8),(2,7),(3,6),(4,5) Second round: ((1,8),(4,5)),((2,7),(3,6)) Third round: (((1,8),(4,5)),((2,7),(3,6))) Since the third round will generate the final winner, you need to output the answer (((1,8),(4,5)),((2,7),(3,6))). Note: The n is in range [2, 212]. We ensure that the input n can be converted into the form 2k, where k is a positive integer.

最强和最弱来对决,其次是次强与次弱对决,这种对战顺序是为了避免强强之间过早对决,从而失去比赛的公平性 #1 迭代 vector<string> v; for (int i = 1; i <= n; ++i) v.push_back(to_string(i)); while (n > 1) { for (int i = 0; i < n / 2; ++i) { v[i] = "(" + v[i] + "," + v[n - i - 1] + ")"; } n /= 2; } return v[0]; #2 递归

[LeetCode#549] Binary Tree Longest Consecutive Sequence II 二叉树最长连续序列之二 Given a binary tree, you need to find the length of Longest Consecutive Path in Binary Tree. Especially, this path can be either increasing or decreasing. For example, [1,2,3,4] and [4,3,2,1] are both considered valid, but the path [1,2,4,3] is not valid. On the other hand, the path can be in the child-Parent-child order, where not necessarily be parent-child order. Example 1: Input: 1 / \ 2 3 Output: 2 Explanation: The longest consecutive path is [1, 2] or [2, 1]. Example 2: Input: 2 / \ 1 3 Output: 3 Explanation: The longest consecutive path is [1, 2, 3] or [3, 2, 1]. Note: All the values of tree nodes are in the range of [-1e7, 1e7].

最长连续序列,我们可以任意的拐弯 递归 1. 后序遍历,每个点和其parent比较。 如果和parent是递增或递减连续序列,将到此点的连续序列长度返回到parent,否则返回{0,0} 2. 每个节点都计算其左右支相连的情况,是否递增递减在子节点已经计算过了,如果不联系,返回的就是0. 这里的1就是本节点 res = max(res, left.first + right.second + 1); res = max(res, left.second + right.first + 1); [Mine] 递归传入parent,在子节点计算和parent的连续关系。似乎有助于减少递增递减判断。

[LeetCode#487] Max Consecutive Ones II 最大连续1的个数之二 Given a binary array, find the maximum number of consecutive 1s in this array if you can flip at most one 0. Example 1: Input: [1,0,1,1,0] Output: 4 Explanation: Flip the first zero will get the the maximum number of consecutive 1s. After flipping, the maximum number of consecutive 1s is 4. Note: The input array will only contain 0 and 1. The length of input array is a positive integer and will not exceed 10,000 Follow up: What if the input numbers come in one by one as an infinite stream? In other words, you can't store all numbers coming from the stream as it's too large to hold in memory. Could you solve it efficiently?

有一次将0翻转成1的机会 #1两个变量,记录间隔一个0的连续两组1的个数,找到更新结果 #2 如果题目中说能翻转k次怎么办呢 维护一个窗口[left,right]来容纳至少k个0。我们遇到了0,就累加zero的个数,然后判断如果此时0的个数大于k,那么我们我们右移左边界left,如果移除掉的nums[left]为0,那么我们zero自减1。如果不大于k,那么我们用窗口中数字的个数来更新res

[LeetCode#546] Remove Boxes 移除盒子 Given several boxes with different colors represented by different positive numbers. You may experience several rounds to remove boxes until there is no box left. Each time you can choose some continuous boxes with the same color (composed of k boxes, k >= 1), remove them and get k*k points. Find the maximum points you can get. Example 1: Input: [1, 3, 2, 2, 2, 3, 4, 3, 1] Output: 23 Explanation: [1, 3, 2, 2, 2, 3, 4, 3, 1] ----> [1, 3, 3, 4, 3, 1] (3*3=9 points) ----> [1, 3, 3, 3, 1] (1*1=1 points) ----> [1, 1] (3*3=9 points) ----> [] (2*2=4 points) Note: The number of boxes n would not exceed 100.

本质就是一个数组,我们每次消去一个或多个数字,并获得相应的分数,让我们求最高能获得的分数。 dp数组应该是一个三维数组dp[i][j][k],表示区间[i, j]中能获得的最大积分,当boxes[i]左边有k个数字跟其相等,那么我们的目标就是要求dp[0][n-1][0]了, 1.我们也能推出dp[i][i][k] = (1+k) * (1+k)这个等式。 2.dp[i][j][k],如果我们移除boxes[i],那么我们得到(1+k)*(1+k) + dp[i+1][j][0] 3.当某个位置m,有boxes[i] == boxes[m]时,我们也应该考虑先移除[i+1,m-1]这部分,我们得到积分dp[i+1][m-1][0],然后再处理剩下的部分,得到积分dp[m][j][k+1] #1 DFS + dp memory #2 迭代 ([Mine]有点不好理解) [Mine] 关键问题比较将现在连续的盒子移除,还是将同颜色的两段盒子连起来移除,哪个得分多。所以需要两个式子 感觉是比较相同数字段自己移除或另外一个相同数字段连起来移除,两两排列组合,找到最佳方案 DFS 正确code应该是 https://blog.csdn.net/yy254117440/article/details/67638980 Burst Balloons, zuma game, remove box, #664 strange printer好像是一个套路? 都是在各个可能区间中搜索一个分割点,将区间分成两个子问题,使整个区间是最佳解。 Burst Balloons dp[i][j] = max(dp[i][j], nums[i - 1]*nums[k]*nums[j + 1] + dp[i][k - 1] + dp[k + 1][j]) ( i ≤ k ≤ j ) zuma game 在球中尝试不同的消除方法,找到最佳方案

[LeetCode#563] Binary Tree Tilt 二叉树的坡度 Given a binary tree, return the tilt of the whole tree. The tilt of a tree node is defined as the absolute difference between the sum of all left subtree node values and the sum of all right subtree node values. Null node has tilt 0. The tilt of the whole tree is defined as the sum of all nodes' tilt. Example: Input: 1 / \ 2 3 Output: 1 Explanation: Tilt of node 2 : 0 Tilt of node 3 : 0 Tilt of node 1 : |2-3| = 1 Tilt of binary tree : 0 + 0 + 1 = 1 Note: The sum of node values in any subtree won't exceed the range of 32-bit integer. All the tilt values won't exceed the range of 32-bit integer.

某个结点的坡度的定义为该结点的左子树之和与右子树之和的差的绝对值,这道题让我们求所有结点的坡度之和 后序遍历来做,因为后序遍历的顺序是左-右-根,那么就会从叶结点开始处理,这样我们就能很方便的计算结点的累加和,同时也可以很容易的根据子树和来计算tilt

[LeetCode#536] Construct Binary Tree from String 从字符串创建二叉树 You need to construct a binary tree from a string consisting of parenthesis and integers. The whole input represents a binary tree. It contains an integer followed by zero, one or two pairs of parenthesis. The integer represents the root's value and a pair of parenthesis contains a child binary tree with the same structure. You always start to construct the left child node of the parent first if it exists. Example: Input: "4(2(3)(1))(6(5))" Output: return the tree root node representing the following tree: 4 / \ 2 6 / \ / 3 1 5 Note: There will only be '(', ')', '-' and '0' ~ '9' in the input string. An empty tree is represented by "" instead of "()".

根据一个字符串来创建一个二叉树,其中结点与其左右子树是用括号隔开,每个括号中又是数字后面的跟括号的模式 #1 递归 先找出根结点值,我们找第一个左括号的位置,如果找不到,说明当前字符串都是数字,直接转化为整型,然后新建结点返回即可。否则的话从当前位置开始遍历,因为当前位置是一个左括号,我们的目标是找到与之对应的右括号的位置 用一个变量cnt来记录左括号的个数,如果遇到左括号,cnt自增1,如果遇到右括号,cnt自减1,这样当某个时刻cnt为0的时候,我们就确定了一个完整的子树的位置。 #2 迭代+ stack 如果遇到的是左括号,什么也不做继续遍历; 如果遇到的是数字,看stack中是否有结点,如果有的话,当前结点就是栈顶结点的子结点,如果栈顶结点没有左子结点,那么此结点就是其左子结点,反之则为其右子结点。之后要将此结点压入栈中。 如果我们遍历到的是右括号,说明栈顶元素的子结点已经处理完了,将其移除栈。

[LeetCode#435] Non-overlapping Intervals 非重叠区间 Given a collection of intervals, find the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping. Note: You may assume the interval's end point is always bigger than its start point. Intervals like [1,2] and [2,3] have borders "touching" but they don't overlap each other. Example 1: Input: [ [1,2], [2,3], [3,4], [1,3] ] Output: 1 Explanation: [1,3] can be removed and the rest of intervals are non-overlapping. Example 2: Input: [ [1,2], [1,2], [1,2] ] Output: 2 Explanation: You need to remove two [1,2] to make the rest of intervals non-overlapping. Example 3: Input: [ [1,2], [2,3] ] Output: 0 Explanation: You don't need to remove any of the intervals since they're already non-overlapping.

根据每个区间的start来做升序排序,然后我们开始要查找重叠区间,判断方法是看如果前一个区间的end大于后一个区间的start,那么一定是重复区间,此时我们结果res自增1,为了保证我们总体去掉的区间数最小,我们去掉那个end值较大的区间,而在代码中,我们并没有真正的删掉某一个区间,而是用一个变量last指向上一个需要比较的区间,我们将last指向end值较小的那个区间;如果两个区间没有重叠,那么此时last指向当前区间,继续进行下一次遍历 [Mine]找到一个overlap的就一定要删除一个区间,而且删除的一定end值大的。删掉之后,end大的区间消失,下次比较,用end小的区间

[LeetCode#492] Construct the Rectangle 构建矩形 For a web developer, it is very important to know how to design a web page's size. So, given a specific rectangular web page's area, your job by now is to design a rectangular web page, whose length L and width W satisfy the following requirements: 1. The area of the rectangular web page you designed must equal to the given target area. 2. The width W should not be larger than the length L, which means L >= W. 3. The difference between length L and width W should be as small as possible. You need to output the length L and the width W of the web page you designed in sequence. Example: Input: 4 Output: [2, 2] Explanation: The target area is 4, and all the possible ways to construct it are [1,4], [2,2], [4,1]. But according to requirement 2, [1,4] is illegal; according to requirement 3, [4,1] is not optimal compared to [2,2]. So the length L is 2, and the width W is 2. Note: The given area won't exceed 10,000,000 and is a positive integer The web page's width and length you designed must be positive integers.

根据面积来求出矩形的长和宽,要求长和宽的差距尽量的小,那么就是说越接近正方形越好 #1 先来判断一下是不是正方行,对面积开方,如果得到的不是整数,说明不是正方形。那么我们取最近的一个整数,看此时能不能整除,如果不行,就自减1,再看能否整除。最坏的情况就是面积是质数,最后减到了1,那么返回结果即可 #2 如果我们不想用开方运算sqrt的话,那就从1开始,看能不能整除,循环的终止条件是看平方值是否小于等于面积

[LeetCode#520] Detect Capital 检测大写格式 Given a word, you need to judge whether the usage of capitals in it is right or not. We define the usage of capitals in a word to be right when one of the following cases holds: All letters in this word are capitals, like "USA". All letters in this word are not capitals, like "leetcode". Only the first letter in this word is capital if it has more than one letter, like "Google". Otherwise, we define that this word doesn't use capitals in a right way. Example 1: Input: "USA" Output: True Example 2: Input: "FlaG" Output: False Note: The input will be a non-empty word consisting of uppercase and lowercase latin letters.

检测大写格式是否正确,规定了三种正确方式,要么都是大写或小写,要么首字母大写,其他情况都不正确。 统计出单词中所有大写字母的个数cnt,再来判断是否属于这三种情况,如果cnt为0,说明都是小写,正确;如果cnt和单词长度相等,说明都是大写,正确;如果cnt为1,且首字母为大写,正确,其他情况均返回false

[LeetCode#482] License Key Formatting 注册码格式化 Now you are given a string S, which represents a software license key which we would like to format. The string S is composed of alphanumerical characters and dashes. The dashes split the alphanumerical characters within the string into groups. (i.e. if there are M dashes, the string is split into M+1 groups). The dashes in the given string are possibly misplaced. We want each group of characters to be of length K (except for possibly the first group, which could be shorter, but still must contain at least one character). To satisfy this requirement, we will reinsert dashes. Additionally, all the lower case letters in the string must be converted to upper case. So, you are given a non-empty string S, representing a license key to format, and an integer K. And you need to return the license key formatted according to the description above. Example 1: Input: S = "2-4A0r7-4k", K = 4 Output: "24A0-R74K" Explanation: The string S has been split into two parts, each part has 4 characters. Example 2: Input: S = "2-4A0r7-4k", K = 3 Output: "24-A0R-74K" Explanation: The string S has been split into three parts, each part has 3 characters except the first part as it could be shorter as said above. Note: The length of string S will not exceed 12,000, and K is a positive integer. String S consists only of alphanumerical characters (a-z and/or A-Z and/or 0-9) and dashes(-). String S is non-empty.

正确的注册码的格式是每四个字符后面跟一个短杠,每一部分的长度为K,第一部分长度可以小于K,另外,字母必须是大写的 #1 从S的尾部往前遍历,把字符加入结果res,每K个后面加一个短杠,那么最后遍历完再把res翻转一下即可 [Mine]从后向前遍历,之后翻转

[LeetCode#477] Total Hamming Distance 全部汉明距离 The Hamming distance between two integers is the number of positions at which the corresponding bits are different. Now your job is to find the total Hamming distance between all pairs of the given numbers. Example: Input: 4, 14, 2 Output: 6 Explanation: In binary representation, the 4 is 0100, 14 is 1110, and 2 is 0010 (just showing the four bits relevant in this case). So the answer will be: HammingDistance(4, 14) + HammingDistance(4, 2) + HammingDistance(14, 2) = 2 + 2 + 2 = 6. Note: Elements of the given array are in the range of 0 to 10^9 Length of the array will not exceed 10^4.

此位能贡献的汉明距离是depend on 0跟1的个数,即每个1和每个0分别的距离累加,我们可以发现其实就是0的个数乘以1的个数。 比如4, 14, 2的倒数第二列,0,1,1,它贡献的汉明距离是2 将各个位上能贡献的汉明距离相加

[LeetCode598] Range Addition II 范围相加之二 Given an m * n matrix M initialized with all 0's and several update operations. Operations are represented by a 2D array, and each operation is represented by an array with two positive integers a and b, which means M[i][j] should be added by one for all 0 <= i < a and 0 <= j < b. You need to count and return the number of maximum integers in the matrix after performing all the operations. Example 1: Input: m = 3, n = 3 operations = [[2,2],[3,3]] Output: 4 Explanation: Initially, M = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] After performing [2,2], M = [[1, 1, 0], [1, 1, 0], [0, 0, 0]] After performing [3,3], M = [[2, 2, 1], [2, 2, 1], [1, 1, 1]] So the maximum integer in M is 2, and there are four of it in M. So return 4. Note: The range of m and n is [1,40000]. The range of a is [1,m], and the range of b is [1,n]. The range of operations size won't exceed 10,000.

每次在ops中给定我们一个横纵坐标,将这个子矩形范围内的数字全部自增1,让我们求最大数字的个数。 #1 只有最小数字组成的边界中的数字才会被每次更新,所以我们想让最小的数字到队首,更优先队列的排序机制是大的数字在队首,所以我们对其取相反数,这样我们最后取出两个队列的队首数字相乘即为结果 #2 每次用ops中的值来更新m和n,取其中较小值,这样遍历完成后,m和n就是最大数矩阵的边界了,

[LeetCode#575] Distribute Candies 分糖果 Given an integer array with even length, where different numbers in this array represent different kinds of candies. Each number means one candy of the corresponding kind. You need to distribute these candies equally in number to brother and sister. Return the maximum number of kinds of candies the sister could gain. Example 1: Input: candies = [1,1,2,2,3,3] Output: 3 Explanation: There are three different kinds of candies (1, 2 and 3), and two candies for each kind. Optimal distribution: The sister has candies [1,2,3] and the brother has candies [1,2,3], too. The sister has three different kinds of candies. Example 2: Input: candies = [1,1,2,3] Output: 2 Explanation: For example, the sister has candies [2,3] and the brother has candies [1,1]. The sister has two different kinds of candies, the brother has only one kind of candies. Note: The length of the given array is in range [2, 10,000], and will be even. The number in given array is in range [-100,000, 100,000].

每种糖的个数不定,平均分给两个人,让我们求其中一个人能拿到的最大的糖的种类数。 利用集合set的自动去重复特性来求出糖的种类数,然后跟n/2比较,取二者之中的较小值返回即可,

[LeetCode#498] Diagonal Traverse 对角线遍历 Given a matrix of M x N elements (M rows, N columns), return all elements of the matrix in diagonal order as shown in the below image. Example: Input: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] Output: [1,2,4,7,5,3,6,8,9] Explanation: Note: The total number of elements of the given matrix will not exceed 10,000.

每移动一次,横纵坐标都要变化,向右上移动的话要坐标加上[-1, 1],向左下移动的话要坐标加上[1, -1] 向右上和左下两个对角线方向遍历的时候都会有越界的可能,但是除了左下角和右上角的位置越界需要改变两个坐标之外,其余的越界只需要改变一个。 vector<vector<int>> dirs{{-1,1}, {1,-1}}; for (int i = 0; i < m * n; ++i) { res[i] = matrix[r][c]; r += dirs[k][0]; c += dirs[k][1]; if (r >= m) {r = m - 1; c += 2; k = 1 - k;} if (c >= n) {c = n - 1; r += 2; k = 1 - k;} if (r < 0) {r = 0; k = 1 - k;} if (c < 0) {c = 0; k = 1 - k;} } Note: change direction k = 1 - k; #2 根据横纵左边之和的奇偶性来判断遍历的方向,然后对于越界情况再单独处理即可 #3 确定每一行的坐标范围,其中下边界low = max(0, i - n + 1),这样可以保证下边界不会小于0,而上边界high = min(i, m - 1),这样也保证了上边界不会大于m-1,如果是偶数层,则从上边界往下边界遍历,反之如果是奇数层,则从下边界往上边界遍历 [Mine]#3找到扫描斜边的r和c的取值范围 int m = matrix.size(), n = matrix[0].size() for (int i = 0; i < m + n - 1; ++i) { int low = max(0, i - n + 1), high = min(i, m - 1); 这里low和high是r的取值范围,i是r和c之和。所以目标就是matrix[r][i - c]

[LeetCode#547] Friend Circles 朋友圈 There are N students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a direct friend of B, and B is a direct friend of C, then A is an indirect friend of C. And we defined a friend circle is a group of students who are direct or indirect friends. Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] = 1, then the ithand jth students are direct friends with each other, otherwise not. And you have to output the total number of friend circles among all the students. Example 1: Input: [[1,1,0], [1,1,0], [0,0,1]] Output: 2 Explanation:The 0th and 1st students are direct friends, so they are in a friend circle. The 2nd student himself is in a friend circle. So return 2. Example 2: Input: [[1,1,0], [1,1,1], [0,1,1]] Output: 1 Explanation:The 0th and 1st students are direct friends, the 1st and 2nd students are direct friends, so the 0th and 2nd students are indirect friends. All of them are in the same friend circle, so return 1. Note: N is in range [1,200]. M[i][i] = 1 for all students. If M[i][j] = 1, then M[j][i] = 1.

求朋友圈的个数,题目中对于朋友圈的定义是可以传递的,比如A和B是好友,B和C是好友,那么即使A和C不是好友,那么他们三人也属于一个朋友圈 #1 DFS搜索,对于某个人,遍历其好友,然后再遍历其好友的好友,那么我们就能把属于同一个朋友圈的人都遍历一遍,我们同时标记出已经遍历过的人,然后累积朋友圈的个数,再去对于没有遍历到的人在找其朋友圈的人,这样就能求出个数。 #2 BFS #3 并查集Union Find while (i != root[i]) { root[i] = root[root[i]]; i = root[i]; }

[LeetCode#424] Longest Repeating Character Replacement 最长重复字符置换 Given a string that consists of only uppercase English letters, you can replace any letter in the string with another letter at most k times. Find the length of a longest substring containing all repeating letters you can get after performing the above operations. Note: Both the string's length and k will not exceed 104. Example 1: Input: s = "ABAB", k = 2 Output: 4 Explanation: Replace the two 'A's with two 'B's or vice versa. Example 2: Input: s = "AABABBA", k = 1 Output: 4 Explanation: Replace the one 'A' in the middle with 'B' and form "AABBBBA". The substring "BBBB" has the longest repeating letters, which is 4.

滑动窗口 如果没有k的限制,让我们求把字符串变成只有一个字符重复的字符串需要的最小置换次数,那么就是字符串的总长度减去出现次数最多的字符的个数。如果加上k的限制,我们其实就是求满足(子字符串的长度减去出现次数最多的字符个数)<=k的最大子字符串长度即可 [Mine]窗口找到第一个满足条件的substring后,继续向前滑动时,即使条件不满足了,也不用缩小。保持窗口大小,向前滑动。因为你不需要找到所有符合条件的substring,你要找的是最大的那个。 新char破坏条件时,就向前滑动窗口,直到窗口内的substring重新符合要求,看新char是否能扩大窗口,窗口大小保持之前套到的最大那个。

[LeetCode#506] Relative Ranks 相对排名 Given scores of N athletes, find their relative ranks and the people with the top three highest scores, who will be awarded medals: "Gold Medal", "Silver Medal" and "Bronze Medal". Example 1: Input: [5, 4, 3, 2, 1] Output: ["Gold Medal", "Silver Medal", "Bronze Medal", "4", "5"] Explanation: The first three athletes got the top three highest scores, so they got "Gold Medal", "Silver Medal" and "Bronze Medal". For the left two athletes, you just need to output their relative ranks according to their scores. Note: N is a positive integer and won't exceed 10,000. All the scores of athletes are guaranteed to be unique.

用score排序,记录坐标。 #1 堆排序 priority_queue #2 快排 sort

[LeetCode#484] Find Permutation 找全排列 By now, you are given a secret signature consisting of character 'D' and 'I'. 'D' represents a decreasing relationship between two numbers, 'I' represents an increasing relationship between two numbers. And our secret signature was constructed by a special integer array, which contains uniquely all the different number from 1 to n (n is the length of the secret signature plus 1). For example, the secret signature "DI" can be constructed by array [2,1,3] or [3,1,2], but won't be constructed by array [3,2,4] or [2,1,3,4], which are both illegal constructing special string that can't represent the "DI" secret signature. On the other hand, now your job is to find the lexicographically smallest permutation of [1, 2, ... n] could refer to the given secret signature in the input. Example 1: Input: "I" Output: [1,2] Explanation: [1,2] is the only legal initial spectial string can construct secret signature "I", where the number 1 and 2 construct an increasing relationship. Example 2: Input: "DI" Output: [2,1,3] Explanation: Both [2,1,3] and [3,1,2] can construct the secret signature "DI", but since we want to find the one with the smallest lexicographical permutation, you need to output [2,1,3] Note: The input string will only contain the character 'D' and 'I'. The length of input string is a positive integer and will not exceed 10,000

由D和I两个字符组成的字符串,分别表示对应位置的升序和降序,要我们根据这个字符串生成对应的数字字符串。 #1 只有D对应的位置附近的数字才需要变换,而且变换方法就是倒置一下字符串,我们要做的就是通过D的位置来确定需要倒置的子字符串的起始位置和长度即可。通过观察,我们需要记录D的起始位置i,还有D的连续个数k,那么我们只需要在数组中倒置[i, i+k]之间的数字即可 #2 对于D先跳过,找到下一个I或结尾,倒序填入之间的数字, [Mine] 对于I间的D,全部倒序转入。 对于每一个I,就是倒序填入only一个数字。连续的I其实还是升序。

[LeetCode#402] Remove K Digits 去掉K位数字 Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible. Note: The length of num is less than 10002 and will be ≥ k. The given num does not contain any leading zero. Example 1: Input: num = "1432219", k = 3 Output: "1219" Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest. Example 2: Input: num = "10200", k = 1 Output: "200" Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes. Example 3: Input: num = "10", k = 2 Output: "0" Explanation: Remove all the digits from the number and it is left with nothing which is 0.

由于数字的相对顺序不变,和#321 Create Maximum Number思路一样 去掉的数字遵从高位优先,除非是相邻的两个数字。相邻数字去掉大的。 for (char c : num) { while (k && res.size() && res.back() > c) { res.pop_back(); --k; } res.push_back(c); } res is the char kept.

[LeetCode#423] Reconstruct Original Digits from English 从英文中重建数字 Given a non-empty string containing an out-of-order English representation of digits 0-9, output the digits in ascending order. Note: Input contains only lowercase English letters. Input is guaranteed to be valid and can be transformed to its original digits. That means invalid inputs such as "abc" or "zerone" are not permitted. Input length is less than 50,000. Example 1: Input: "owoztneoer" Output: "012" Example 2: Input: "fviefuro" Output: "45"

由于题目中限定了输入的字符串一定是有效的,那么不会出现无法成功重建的情况,这里需要用个trick。 1. 现有些的单词的字符是独一无二的,比如z,只出现在zero中,还有w,u,x,g这四个单词,分别只出现在two,four,six,eight中,那么这五个数字的个数就可以被确定了, 2. 由于含有o的单词有zero,two,four,one,其中前三个都被确定了,那么one的个数也就知道了; 3. 由于含有h的单词有eight,three,其中eight个数已知,那么three的个数就知道了; 4. 由于含有f的单词有four,five,其中four个数已知,那么five的个数就知道了; 5. 由于含有s的单词有six,seven,其中six个数已知,那么seven的个数就知道了; 6. 由于含有i的单词有six,eight,five,nine,其中前三个都被确定了,那么nine的个数就知道了 按这个顺序"zero", "two", "four", "six", "eight", "one", "three", "five", "seven", "nine"就能找出所有的个数了

[LeetCode#475] Heaters 加热器 Winter is coming! Your first job during the contest is to design a standard heater with fixed warm radius to warm all the houses. Now, you are given positions of houses and heaters on a horizontal line, find out minimum radius of heaters so that all houses could be covered by those heaters. So, your input will be the positions of houses and heaters seperately, and your expected output will be the minimum radius standard of heaters. Note: Numbers of houses and heaters you are given are non-negative and will not exceed 25000. Positions of houses and heaters you are given are non-negative and will not exceed 10^9. As long as a house is in the heaters' warm radius range, it can be warmed. All the heaters follow your radius standard and the warm radius will the same. Example 1: Input: [1,2,3],[2] Output: 1 Explanation: The only heater was placed in the position 2, and if we use the radius 1 standard, then all the houses can be warmed. Example 2: Input: [1,2,3,4],[1,4] Output: 1 Explanation: The two heater was placed in the position 1 and 4. We need to use radius 1 standard, then all the houses can be warmed.

目标是houses中的每一个数字都要被cover到 排序 #1 在heater中两个数一组进行检查,如果下面一个heater和当前house位置差的绝对值小于等于当前heater和当前house位置差的绝对值,即下一个heater可以以更短距离cover这个house,继续遍历下一个heater,如果不行,就说明找到了这个house的最短cover heater,更新res,遍历下一个house #2 二分查找法来快速找到第一个大于等于当前house位置的数,如果这个数存在,那么我们可以算出其和house的差值,并且如果这个数不是heater的首数字,我们可以算出house和前面一个数的差值,这两个数中取较小的为cover当前house的最小半径,然后我们每次更新结果res即可 [Mine]house的cover heater一定是在它邻近的一个或两个heater中距离最近的一个。

[LeetCode#448] Find All Numbers Disappeared in an Array 找出数组中所有消失的数字 Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. Find all the elements of [1, n] inclusive that do not appear in this array. Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space. Example: Input: [4,3,2,7,8,2,3,1] Output: [5,6]

类似#442, 核心是就是找nums[i]和nums[nums[i] - 1]的关系 #1 对于每个数字nums[i],如果其对应的nums[nums[i] - 1]是正数,我们就赋值为其相反数,如果已经是负数了,就不变了,那么最后我们只要把留下的正数对应的位置加入结果res中即可 #2 将nums[i]置换到其对应的位置nums[nums[i]-1]上去。 最后在对应位置检验,如果nums[i]和i+1不等,那么我们将i+1存入结果res中即可 #3 在nums[nums[i]-1]位置累加数组长度n,注意nums[i]-1有可能越界,所以我们需要对n取余

[LeetCode#534] Design TinyURL 设计精简URL地址

系统设计的题

[LeetCode#518] Coin Change 2 硬币找零之二 You are given coins of different denominations and a total amount of money. Write a function to compute the number of combinations that make up that amount. You may assume that you have infinite number of each kind of coin. Note: You can assume that 0 <= amount <= 5000 1 <= coin <= 5000 the number of coins is less than 500 the answer is guaranteed to fit into signed 32-bit integer Example 1: Input: amount = 5, coins = [1, 2, 5] Output: 4 Explanation: there are four ways to make up the amount: 5=5 5=2+2+1 5=2+1+1+1 5=1+1+1+1+1 Example 2: Input: amount = 3, coins = [2] Output: 0 Explanation: the amount of 3 cannot be made up just with coins of 2. Example 3: Input: amount = 10, coins = [10] Output: 1

组成给定钱数总共有多少种不同的方法。 #1 DP dp[i][j]表示用前i个硬币组成钱数为j的不同组合方法 dp[i][j] = dp[i - 1][j] + (j >= coins[i - 1] ? dp[i][j - coins[i - 1]] : 0) dp[i][0] = 1; #2 DP,空间优化为一维数组 #3 递归 + Memory 当用到最后一个硬币时,我们判断当前还剩点钱数是否能整除这个硬币,不能的话就返回0,否则返回1 if (amount == 0) return 1; else if (idx >= coins.size()) return 0; else if (idx == coins.size() - 1) return amount % coins[idx] == 0;

[LeetCode#533] Lonely Pixel II 孤独的像素之二 Given a picture consisting of black and white pixels, and a positive integer N, find the number of black pixels located at some specific row R and column C that align with all the following rules: 1. Row R and column C both contain exactly N black pixels. 2. For all rows that have a black pixel at column C, they should be exactly the same as row R The picture is represented by a 2D char array consisting of 'B' and 'W', which means black and white pixels respectively. Example: Input: [['W', 'B', 'W', 'B', 'B', 'W'], ['W', 'B', 'W', 'B', 'B', 'W'], ['W', 'B', 'W', 'B', 'B', 'W'], ['W', 'W', 'B', 'W', 'B', 'W']] N = 3 Output: 6 Explanation: All the bold 'B' are the black pixels we need (all 'B's at column 1 and 3). 0 1 2 3 4 5 column index 0 [['W', 'B', 'W', 'B', 'B', 'W'], 1 ['W', 'B', 'W', 'B', 'B', 'W'], 2 ['W', 'B', 'W', 'B', 'B', 'W'], 3 ['W', 'W', 'B', 'W', 'B', 'W']] row index Take 'B' at row R = 0 and column C = 1 as an example: Rule 1, row R = 0 and column C = 1 both have exactly N = 3 black pixels. Rule 2, the rows have black pixel at column C = 1 are row 0, row 1 and row 2. They are exactly the same as row R = 0. Note: The range of width and height of the input 2D array is [1,200].

给了一个整数N,说对于均含有N个个黑像素的某行某列,如果该列中所有的黑像素所在的行都相同的话,该列的所有黑像素均为孤独的像素 #1 用哈希表来做的,以黑像素出现个数为N的行组成的字符串为key,以其出现次数之间的映射 统计每列的黑像素的个数 遍历哈希表,找到出现次数刚好为N的字符串,说明矩阵中有N个相同的为这样字符串的行,而且该行中的黑像素的个数也刚好为N个,那么第二个条件就已经满足了。 检测每个黑像素的列上黑像素统计。 [Mine]利用拼接字符串来快速匹配符合条件二的行。

[LeetCode#472] Concatenated Words 连接的单词 Given a list of words (without duplicates), please write a program that returns all concatenated words in the given list of words. A concatenated word is defined as a string that is comprised entirely of at least two shorter words in the given array. Example: Input: ["cat","cats","catsdogcats","dog","dogcatsdog","hippopotamuses","rat","ratcatdogcat"] Output: ["catsdogcats","dogcatsdog","ratcatdogcat"] Explanation: "catsdogcats" can be concatenated by "cats", "dog" and "cats"; "dogcatsdog" can be concatenated by "dog", "cats" and "dog"; "ratcatdogcat" can be concatenated by "rat", "cat", "dog" and "cat". Note: The number of elements of the given array will not exceed 10,000 The length sum of elements in the given array will not exceed 600,000. All the input string will only include lower case letters. The returned elements order does not matter.

给了一个由单词组成的数组,某些单词是可能由其他的单词组成的,让我们找出所有这样的单词。 similar to #139 Word Break DP[i]表示在这个word中,到0~i子串是否完全由dict拼接出。 对每一个word的每个子串,从短子串到长子串,计算其是否在dict中有。 DP[i]=DP[j] && dict.count(word.substr(j, i - j)) 0<=j<i

[LeetCode#567] Permutation in String 字符串中的全排列 Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. In other words, one of the first string's permutations is the substring of the second string. Example 1: Input:s1 = "ab" s2 = "eidbaooo" Output:True Explanation: s2 contains one permutation of s1 ("ba"). Example 2: Input:s1= "ab" s2 = "eidboaoo" Output: False Note: The input strings only contain lower case letters. The length of both given strings is in range [1, 10,000].

给了两个字符串s1和s2,问我们s1的全排列的字符串任意一个是否为s2的字串 #1 使用两个哈希表来做的情况,我们先来分别统计s1和s2中前n1个字符串中各个字符出现的次数 保持窗口大小,滑动窗口,每次都比较一下两个哈希表的情况,如果相等,说明存在 #2 一个哈希表加上双指针。 哈希表还是给s1的,双指针标识窗口,哈希表计数减减(右指针前移)加加(左指针前移),目标是哈希表全0且窗口大小为s1。 [Mine]一旦发现杂质,或多余元素,缩小窗口直至错误清除 #2 一个哈希表加上双指针 哈希表还是给s1的,双指针标识窗口,右指针前移,计数减减,cnt表示匹配上的s1字符个数,当cnt=0,说明s1全匹配上了,如果窗口大小为s1,return true,如果窗口过大,缩小窗口,更改计数和cnt。目标是cnt=0且窗口大小为s1

[LeetCode#542] 01 Matrix 零一矩阵 Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell. The distance between two adjacent cells is 1. Example 1: Input: 0 0 0 0 1 0 0 0 0 Output: 0 0 0 0 1 0 0 0 0 Example 2: Input: 0 0 0 0 1 0 1 1 1 Output: 0 0 0 0 1 0 1 2 1 Note: The number of elements of the given matrix will not exceed 10,000. There are at least one 0 in the given matrix. The cells are adjacent in only four directions: up, down, left and right.

给了我们一个只有0和1的矩阵,让我们求每一个1到离其最近的0的距离 #1 BFS 将值为0的点都存入queue,开始BFS遍历,从queue中取出一个数字,遍历其周围四个点,如果越界或者周围点的值小于等于当前值,则直接跳过。因为周围点的距离更小的话,就没有更新的必要,否则将周围点的值更新为当前值加1,然后把周围点的坐标加入queue #2 二次扫描 建立一个和matrix大小相等的矩阵res,初始化为很大的值,这里我们用INT_MAX-1 当遇到为0的位置,我们将结果res矩阵的对应位置也设为0 第一次扫描的时候,比较其左边和上边的位置,取其中较小的值,再加上1,来更新结果res中的对应位置 第二次遍历就要比较右和下的方向 [Mine]从左上,将0向1的区域递增演进,每次和之前值取小值;从右下,同样演进。 Q:为什么先从左上? A:因为标准的横纵坐标递增遍历,就是从左到右,从上到下遍历,这样配合遇到0,res对应位置置0,保证了每个点的左上如果是0,res的0已经置好

[LeetCode#524] Longest Word in Dictionary through Deleting 删除后得到的字典中的最长单词 Given a string and a string dictionary, find the longest string in the dictionary that can be formed by deleting some characters of the given string. If there are more than one possible results, return the longest word with the smallest lexicographical order. If there is no possible result, return the empty string. Example 1: Input: s = "abpcplea", d = ["ale","apple","monkey","plea"] Output: "apple" Example 2: Input: s = "abpcplea", d = ["a","b","c"] Output: "a" Note: All the strings in the input will only contain lower-case letters. The size of the dictionary won't exceed 1,000. The length of all the strings in the input won't exceed 1,000.

给了我们一个字符串,和一个字典,让我们找到字典中最长的一个单词,这个单词可以通过给定单词通过删除某些字符得到 #1 给字典从大到小排序,如果长度相等的就按字母顺序来排,判断子序列。 #2 直接一个个判断子序列,更新res

[LeetCode#409] Longest Palindrome 最长回文串 Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters. This is case sensitive, for example "Aa" is not considered a palindrome here. Note: Assume the length of given string will not exceed 1,010. Example: Input: "abccccdd" Output: 7 Explanation: One longest palindrome that can be built is "dccaccd", whose length is 7.

给了我们一个字符串,让我们找出可以组成的最长的回文串的长度,由于字符顺序打乱 #1 所有偶数个字符的出现总和,然后如果有奇数个字符的话,我们取取出其最大偶数,然后最后结果加1即可 #2 字符串长度减去max of 0和奇数字符数量-1。 s.size() - max(0, odds - 1); [Mine]所有奇数数量的字符,每个组字符要浪费一个字符,最多只有一组奇数数量字符可以不浪费地用在回文串中。

[LeetCode#459] Repeated Substring Pattern 重复子字符串模式 Given a non-empty string check if it can be constructed by taking a substring of it and appending multiple copies of the substring together. You may assume the given string consists of lowercase English letters only and its length will not exceed 10000. Example 1: Input: "abab" Output: True Explanation: It's the substring "ab" twice. Example 2: Input: "aba" Output: False Example 3: Input: "abcabcabcabc" Output: True Explanation: It's the substring "abc" four times. (And the substring "abcabc" twice.)

给了我们一个字符串,问其是否能拆成n个重复的子串 #1 从原字符串长度的一半遍历到1,如果当前长度能被总长度整除(二分,三分,四分。。。),说明可以分成若干个子字符串,我们将这些子字符串拼接起来看跟原字符串是否相等 #2 一位数组dp[i]表示,到位置i-1为止的重复字符串的字符个数,不包括被重复的那个字符串 如果是"abcabcabc",那么dp数组为[0 0 0 0 1 2 3 4 5 6] while (i < n) { if (str[i] == str[j]) dp[++i] = ++j; else if (j == 0) ++i; else j = dp[j]; } return dp[n] && (dp[n] % (n - dp[n]) == 0); [Mine]感觉就是求KMP算法中的next数组时的当前位置的最大相同前缀后缀的长度 [Mine]最后一个字符有相同前后缀,并且最长前后缀能够整除剩余部分,即前后缀一定大于等于剩余部分,另外根据前后缀属性,剩余部分很可能就是能填满整个字符串的最短重复子字符串。

[LeetCode#564] Find the Closest Palindrome 寻找最近的回文串 Given an integer n, find the closest integer (not including itself), which is a palindrome. The 'closest' is defined as absolute difference minimized between two integers. Example 1: Input: "123" Output: "121" Note: The input n is a positive integer represented by string, whose length will not exceed 18. If there is a tie, return the smaller one as answer.

给了我们一个数字,让我们找到其最近的回文数,而且说明了这个最近的回文数不能是其本身。比如如果给你个131,那么就需要返回121。而且返回的回文数可能位数还不同,比如当n为100的时候,我们就应该返回99,或者给了我们99时,需要返回101 1. 范围:n为三位数,那么其最近回文数的范围在[99, 1001]之间 2. 对原数的修改:一种是原数本来就是回文数,这种情况下,我们需要改变中间的那个数字,要么增加1,要么减小1,比如121,可以变成111和131。另一种情况是原数不是回文数,我们只需要改变右半边就行了 3. 在五个candidates中找出和原数绝对差最小的那个返回,记得别忘了在集合中删除原数,因为如果原数时回文的话, i=0时就把自己也加入集合了 [Mine]可能在这几种情况 1. pow(10, len) + 1 or pow(10, len-1) - 1, example: 99->101 2. len is odd, change mid (-1, +1) and right, example:131->121 3. len is even, change right.

[LeetCode#455] Assign Cookies 分点心 Assume you are an awesome parent and want to give your children some cookies. But, you should give each child at most one cookie. Each child i has a greed factor gi, which is the minimum size of a cookie that the child will be content with; and each cookie j has a size sj. If sj >= gi, we can assign the cookie j to the child i, and the child i will be content. Your goal is to maximize the number of your content children and output the maximum number. Note: You may assume the greed factor is always positive. You cannot assign more than one cookie to one child. Example 1: Input: [1,2,3], [1,1] Output: 1 Explanation: You have 3 children and 2 cookies. The greed factors of 3 children are 1, 2, 3. And even though you have 2 cookies, since their size is both 1, you could only make the child whose greed factor is 1 content. You need to output 1. Example 2: Input: [1,2], [1,2,3] Output: 2 Explanation: You have 2 children and 3 cookies. The greed factors of 2 children are 1, 2. You have 3 cookies and their sizes are big enough to gratify all of the children, You need to output 2.

给了我们一堆cookie,每个cookie的大小不同,还有一堆小朋友,每个小朋友的胃口也不同的,问我们当前的cookie最多能满足几个小朋友。 对两个数组进行排序,让小的在前面。然后我们先拿最小的cookie给胃口最小的小朋友,看能否满足,能的话,我们结果res自加1,然后再拿下一个cookie去满足下一位小朋友;如果当前cookie不能满足当前小朋友,那么我们就用下一块稍大一点的cookie去尝试满足当前的小朋友。当cookie发完了或者小朋友没有了我们停止遍历

[LeetCode#464] Can I Win 我能赢吗 In the "100 game," two players take turns adding, to a running total, any integer from 1..10. The player who first causes the running total to reach or exceed 100 wins. What if we change the game so that players cannot re-use integers? For example, two players might take turns drawing from a common pool of numbers of 1..15 without replacement until they reach a total >= 100. Given an integer maxChoosableInteger and another integer desiredTotal, determine if the first player to move can force a win, assuming both players play optimally. You can always assume that maxChoosableInteger will not be larger than 20 and desiredTotal will not be larger than 300. Example Input: maxChoosableInteger = 10 desiredTotal = 11 Output: false Explanation: No matter which integer the first player choose, the first player will lose. The first player can choose an integer from 1 up to 10. If the first player choose 1, the second player can only choose integers from 2 up to 10. The second player will win by choosing 10 and get a total = 11, which is >= desiredTotal. Same with other integers chosen by the first player, the second player will always win.

给了我们一堆数字,然后两个人,每人每次选一个数字,看数字总数谁先到给定值 递归+Memo 如果给定的数字范围大于等于目标值的话,直接返回true。 如果给定的数字总和小于目标值的话,说明谁也没法赢,返回false。 使用一个整型数按位来记录数组中的某个数字是否使用,so bits int used record当前可选数字的状态,以它为key,hashmap记录当前状态已知的结果 bool canWin(int length, int total, int used, unordered_map<int, bool>& m) { if (m.count(used)) return m[used]; for (int i = 0; i < length; ++i) { int cur = (1 << i); if ((cur & used) == 0) { if (total <= i + 1 || !canWin(length, total - (i + 1), cur | used, m)) { m[used] = true; return true; } } } m[used] = false; return false; } [Mine]先手能赢,即自己能赢 或 对手会输

[LeetCode#593] Valid Square 验证正方形 Given the coordinates of four points in 2D space, return whether the four points could construct a square. The coordinate (x,y) of a point is represented by an integer array with two integers. Example: Input: p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,1] Output: True Note: All the input integers are in the range [-10000, 10000]. A valid square has four equal sides with positive length and four equal angles (90-degree angles). Input points have no order.

给了我们四个点,让我们验证这四个点是否能组成一个正方形 Note: 即便四个角都是直角,也不能说明一定就是正方形,还有可能是矩形 正方形的四条边相等,两条对角线相等,满足这两个条件的四边形一定是正方形。 对四个点,两两之间算距离,如果计算出某两个点之间距离为0,说明两点重合了,直接返回false,如果不为0,那么我们就建立距离和其出现次数之间的映射,最后如果我们只得到了两个不同的距离长度,那么就说明是正方形了

[LeetCode#479] Largest Palindrome Product 最大回文串乘积 Find the largest palindrome made from the product of two n-digit numbers. Since the result could be very large, you should return the largest palindrome mod 1337. Example: Input: 2 Output: 987 Explanation: 99 x 91 = 9009, 9009 % 1337 = 987 Note: The range of n is [1,8].

给我们一个数字n,问两个n位数的乘积组成的最大回文数是多少,返回的结果对1337取余。 当n>1时,两个n位数乘积的最大回文数一定是2n位的 确定出n位数的范围,最大值upper (10^n-1),可以取到,最小值lower(upper / 10),不能取到。然后我们遍历这区间的所有数字,对于每个遍历到的数字,我们用当前数字当作回文数的前半段,将其翻转一下拼接到后面,此时组成一个回文数。来验证这个回文数能否由两个n位数相乘的来。 验证方法:从upper开始遍历,结束位置是当前数的平方大于回文数,因为我们遍历的是相乘得到回文数的两个数中的较大数,一旦超过这个范围,就变成较小数了,就重复计算了。 [Mine]从可能的结果入手,进行验证。 从upper到lower,拼回文数,验证。 验证: for (long j = upper; j * j > 回文数; --j) { if (回文数 % j == 0)

[LeetCode#557] Reverse Words in a String III 翻转字符串中的单词之三 Given a string, you need to reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order. Example 1: Input: "Let's take LeetCode contest" Output: "s'teL ekat edoCteeL tsetnoc" Note: In the string, each word is separated by single space and there will not be any extra space in the string.

翻转字符串中的每个单词 用两个指针,分别指向每个单词的开头和结尾位置,确定了单词的首尾位置后,再用两个指针对单词进行首尾交换即可,有点像验证回文字符串的方法

[LeetCode#451] Sort Characters By Frequency 根据字符出现频率排序 Given a string, sort it in decreasing order based on the frequency of characters. Example 1: Input: "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: "cccaaa" Output: "cccaaa" Explanation: Both 'c' and 'a' appear three times, so "aaaccc" is also a valid answer. Note that "cacaca" is incorrect, as the same characters must be together. Example 3: Input: "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.

肯定要先统计出每个字符出现的个数 #1 利用优先队列的自动排序的特点,把个数和字符组成pair放到优先队列里排好序后,再取出来组成结果res即可 #2 使用STL自带的sort来做 #3 因为某个字符的出现次数不可能超过s的长度,所以我们将每个字符根据其出现次数放入数组中的对应位置,那么最后我们只要从后往前遍历数组所有位置,将不为空的位置的字符串加入结果res中即可 [Mine]一定要记住#3的基数排序方法

[LeetCode#425] Word Squares 单词平方 Given a set of words (without duplicates), find all word squares you can build from them. A sequence of words forms a valid word square if the kth row and column read the exact same string, where 0 ≤ k < max(numRows, numColumns). For example, the word sequence ["ball","area","lead","lady"] forms a word square because each word reads the same both horizontally and vertically. b a l l a r e a l e a d l a d y Note: There are at least 1 and at most 1000 words. All words will have the exact same length. Word length is at least 1 and at most 5. Each word contains only lowercase English alphabet a-z. Example 1: Input: ["area","lead","wall","lady","ball"] Output: [ [ "wall", "area", "lead", "lady" ], [ "ball", "area", "lead", "lady" ] ] Explanation: The output consists of two word squares. The order of output does not matter (just the order of words in each word square matters). Example 2: Input: ["abat","baba","atan","atal"] Output: [ [ "baba", "abat", "baba", "atan" ], [ "baba", "abat", "baba", "atal" ] ] Explanation: The output consists of two word squares. The order of output does not matter (just the order of words in each word square matters).

能快速的通过前缀来判断某个单词是否存在,这是解题的关键 #1 利用哈希表来建立前缀和所有包含此前缀单词的集合之前的映射 #2 建立前缀树Trie,在node里面加上以它为prefix所有可能的word,List<String> 第一个单词:""为前缀,在words数组里随便取一个word1,确定长度 第二个单词:在剩下的words里取出一个以word1[1]为前缀的word2 第三个单词:在剩下的里取出一个以word1[2]+word2[2]为前缀的word3 第四个单词:在剩下的里取出一个以word1[3]+word2[3]+word3[3]为前缀的word4 第五个单词:在剩下的里取出一个以word1[4]+word2[4]+word3[4]+word4[4]为前缀的word5 [Mine] 以四乘四Square看,左上右下对角线字母无需Mirror,其他都是沿对角线Mirror。所以竖排扫描与横排前缀相同。DFS来递归穷举出符合条件的squares

[LeetCode#463] Island Perimeter 岛屿周长 You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells). The island doesn't have "lakes" (water inside that isn't connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don't exceed 100. Determine the perimeter of the island. Example: [[0,1,0,0], [1,1,1,0], [0,1,0,0], [1,1,0,0]] Answer: 16 Explanation: The perimeter is the 16 yellow stripes in the image below:

若干连在一起的格子形成了一个小岛,规定了图中只有一个相连的岛,且岛中没有湖,让我们求岛的周长 #1 我们对于每个格子的四条边分别来处理,首先看左边的边,只有当左边的边处于第一个位置或者当前格子的左面没有岛格子的时候,左边的边计入周长。其他三条边的分析情况都跟左边的边相似 #2 对于每个岛屿格子先默认加上四条边,然后检查其左面和上面是否有岛屿格子,有的话分别减去两条边,这样也能得到正确的结果

[LeetCode#447] Number of Boomerangs 回旋镖的数量 Given n points in the plane that are all pairwise distinct, a "boomerang" is a tuple of points (i, j, k) such that the distance between i and j equals the distance between i and k (the order of the tuple matters). Find the number of boomerangs. You may assume that n will be at most 500 and coordinates of points are all in the range [-10000, 10000] (inclusive). Example: Input: [[0,0],[1,0],[2,0]] Output: 2 Explanation: The two boomerangs are [[1,0],[0,0],[2,0]] and [[1,0],[2,0],[0,0]]

要求第一个点和第二个点之间的距离跟第一个点和第三个点之间的距离相等. 如果有n个点和a距离相等,那么排列方式为n(n-1),这属于最简单的排列组合问题了 遍历所有点,让每个点都做一次点a,然后遍历其他所有点,统计和a距离相等的点有多少个,然后分别带入n(n-1)计算结果并累加到res中,只有当n大于等于2时,res值才会真正增加 int a = points[i].first - points[j].first; int b = points[i].second - points[j].second; ++m[a * a + b * b]; for (auto it = m.begin(); it != m.end(); ++it) { res += it->second * (it->second - 1); } [Mine]虽然这里实际是c*c,但我们实际需要知道距离相同的点个数,所以无所谓。

[LeetCode#434] Number of Segments in a String 字符串中的分段数量 Count the number of segments in a string, where a segment is defined to be a contiguous sequence of non-space characters. Please note that the string does not contain any non-printable characters. Example: Input: "Hello, my name is John" Output: 5

计算空格

[LeetCode#436] Find Right Interval 找右区间 Given a set of intervals, for each of the interval i, check if there exists an interval j whose start point is bigger than or equal to the end point of the interval i, which can be called that j is on the "right" of i. For any interval i, you need to store the minimum interval j's index, which means that the interval j has the minimum start point to build the "right" relationship for interval i. If the interval j doesn't exist, store -1 for the interval i. Finally, you need output the stored value of each interval as an array. Note: You may assume the interval's end point is always bigger than its start point. You may assume none of these intervals have the same start point. Example 1: Input: [ [1,2] ] Output: [-1] Explanation: There is only one interval in the collection, so it outputs -1. Example 2: Input: [ [3,4], [2,3], [1,2] ] Output: [-1, 0, 1] Explanation: There is no satisfied "right" interval for [3,4]. For [2,3], the interval [3,4] has minimum-"right" start point; For [1,2], the interval [2,3] has minimum-"right" start point. Example 3: Input: [ [1,4], [2,3], [3,4] ] Output: [-1, 2, -1] Explanation: There is no satisfied "right" interval for [1,4] and [3,4]. For [2,3], the interval [3,4] has minimum-"right" start point.

让我们找每个区间的最近右区间,要保证右区间的start要大于等于当前区间的end start值降序排列。然后我们遍历区间集合,对于每个区间,我们在数组中找第一个小于当前区间的end值的位置,如果数组中第一个数就小于当前区间的end,那么说明该区间不存在右区间,结果res中加入-1;如果找到了第一个小于当前区间end的位置,那么往前推一个就是第一个大于等于当前区间end的start

[LeetCode#499] The Maze III 迷宫之三 There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolling up (u), down (d), left (l) or right (r), but it won't stop rolling until hitting a wall. When the ball stops, it could choose the next direction. There is also a hole in this maze. The ball will drop into the hole if it rolls on to the hole. Given the ball position, the hole position and the maze, find out how the ball could drop into the hole by moving the shortest distance. The distance is defined by the number of empty spaces traveled by the ball from the start position (excluded) to the hole (included). Output the moving directions by using 'u', 'd', 'l' and 'r'. Since there could be several different shortest ways, you should output the lexicographically smallest way. If the ball cannot reach the hole, output "impossible". The maze is represented by a binary 2D array. 1 means the wall and 0 means the empty space. You may assume that the borders of the maze are all walls. The ball and the hole coordinates are represented by row and column indexes. Example 1 Input 1: a maze represented by a 2D array 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 Input 2: ball coordinate (rowBall, colBall) = (4, 3) Input 3: hole coordinate (rowHole, colHole) = (0, 1) Output: "lul" Explanation: There are two shortest ways for the ball to drop into the hole. The first way is left -> up -> left, represented by "lul". The second way is up -> left, represented by 'ul'. Both ways have shortest distance 6, but the first way is lexicographically smaller because 'l' < 'u'. So the output is "lul". Example 2 Input 1: a maze represented by a 2D array 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 1 0 0 1 0 1 0 0 0 Input 2: ball coordinate (rowBall, colBall) = (4, 3) Input 3: hole coordinate (rowHole, colHole) = (3, 0) Output: "impossible" Explanation: The ball cannot reach the hole. Note: There is only one ball and one hole in the maze. Both the ball and hole exist on an empty space, and they will not be at the same position initially. The given maze does not contain border (like the red rectangle in the example pictures), but you could assume the border of the maze are all walls. The maze contains at least 2 empty spaces, and the width and the height of the maze won't exceed 30.

让球在最小步数内滚到陷阱之中,此时返回的并不是最小步数,而是滚动的方向,用u, r, d, l 这四个字母来分别表示上右下左,而且在步数相等的情况下,让我们返回按字母排序小的答案。 # Queue 迭代 dists[i][j]表示到达(i,j)这个位置时需要的最小步数,我们都初始化为整型最大值,在后在遍历的过程中不断用较小值来更新每个位置的步数值。我们还需要用一个哈希表来建立每个位置跟滚到该位置的方向字符串之间的映射,这里我们用一个trick,将二维坐标转(i,j)为一个数字i*n+j,这实际上就是把二维数组拉成一维数组的操作 [Mine]记录路径上每个拐点的最短步数和最符合题意path,用queue记录备选方向。拐点不是已知最短,就不入Queue #2 DFS

[LeetCode#517] Super Washing Machines 超级洗衣机 You have n super washing machines on a line. Initially, each washing machine has some dresses or is empty. For each move, you could choose any m (1 ≤ m ≤ n) washing machines, and pass one dress of each washing machine to one of its adjacent washing machines at the same time . Given an integer array representing the number of dresses in each washing machine from left to right on the line, you should find the minimum number of moves to make all the washing machines have the same number of dresses. If it is not possible to do it, return -1. Example1 Input: [1,0,5] Output: 3 Explanation: 1st move: 1 0 <-- 5 => 1 1 4 2nd move: 1 <-- 1 <-- 4 => 2 1 3 3rd move: 2 1 <-- 3 => 2 2 2 Example2 Input: [0,3,0] Output: 2 Explanation: 1st move: 0 <-- 3 0 => 1 2 0 2nd move: 1 2 --> 0 => 1 1 1 Example3 Input: [0,2,0] Output: -1 Explanation: It's impossible to make all the three washing machines have the same number of dresses. Note: The range of n is [1, 10000]. The range of dresses number in a super washing machine is [0, 1e5].

许多洗衣机,每个洗衣机里的衣服数不同,每个洗衣机每次只允许向相邻的洗衣机转移一件衣服,问要多少次才能使所有洗衣机的衣服数相等 int res = 0, cnt = 0, avg = sum / machines.size(); for (int m : machines) { cnt += m - avg; res = max(res, max(abs(cnt), m - avg)); } [Mine]差值逐一归并。 [Mine] Q:为什么m-avg要加入res的update中,而且cnt要加绝对值,m-avg不能加 A:为什么m-avg不能加绝对值,因为可能选取m-avg的条件是, 仅当cnt从负值反转成正值时,最大次数不能假设为归并后的指(填坑之后的值),而是应该选正数的原始值m-avg,因为正值只能一次一个的转走,而负值是可以从两边转来填坑。 如果是正值反转为负值,说明正值前出现了一个坑,而反转说明坑从遍历的方向无法填满,那么这个坑一定同时会从另外一边的正值*同时*填上。 例如:[3, 6, 3] 和[6, 3, 6],第一个需要两次,而第二个一次就够了

[LeetCode#588] Design In-Memory File System 设计内存文件系统 Design an in-memory file system to simulate the following functions: ls: Given a path in string format. If it is a file path, return a list that only contains this file's name. If it is a directory path, return the list of file and directory names in this directory. Your output (file and directory names together) should in lexicographic order. mkdir: Given a directory path that does not exist, you should make a new directory according to the path. If the middle directories in the path don't exist either, you should create them as well. This function has void return type. addContentToFile: Given a file path and file content in string format. If the file doesn't exist, you need to create that file containing given content. If the file already exists, you need to append given content to original content. This function has void return type. readContentFromFile: Given a file path, return its content in string format. Example: Input: ["FileSystem","ls","mkdir","addContentToFile","ls","readContentFromFile"] [[],["/"],["/a/b/c"],["/a/b/c/d","hello"],["/"],["/a/b/c/d"]] Output: [null,[],null,null,["a"],"hello"] Explanation: filesystem Note: You can assume all file or directory paths are absolute paths which begin with / and do not end with /except that the path is just "/". You can assume that all operations will be passed valid parameters and users will not attempt to retrieve file content or list a directory or file that does not exist. You can assume that all directory names and file names only contain lower-case letters, and same names won't exist in the same directory.

设计一个内存文件系统,实现显示当前文件,创建文件,添加内容到文件,读取文件内容等功能 两个哈希表来做,其中dirs建立了路径和其对应的包含所有文件和文件夹的集合之间的映射,files建立了文件的路径跟其内容之间

[LeetCode#531] Lonely Pixel I 孤独的像素之一 Given a picture consisting of black and white pixels, find the number of black lonely pixels. The picture is represented by a 2D char array consisting of 'B' and 'W', which means black and white pixels respectively. A black lonely pixel is character 'B' that located at a specific position where the same row and same column don't have any other black pixels. Example: Input: [['W', 'W', 'B'], ['W', 'B', 'W'], ['B', 'W', 'W']] Output: 3 Explanation: All the three 'B's are black lonely pixels. Note: The range of width and height of the input 2D array is [1,500].

该黑像素所在的行和列中没有其他的黑像素 将各行各列的黑像素的个数都统计出来,然后再扫描所有的黑像素一次,看其是否是该行该列唯一的存在,是的话就累加计数器即可

[LeetCode#452] Minimum Number of Arrows to Burst Balloons 最少数量的箭引爆气球 There are a number of spherical balloons spread in two-dimensional space. For each balloon, provided input is the start and end coordinates of the horizontal diameter. Since it's horizontal, y-coordinates don't matter and hence the x-coordinates of start and end of the diameter suffice. Start is always smaller than end. There will be at most 104 balloons. An arrow can be shot up exactly vertically from different points along the x-axis. A balloon with xstart and xend bursts by an arrow shot at x if xstart ≤ x ≤ xend. There is no limit to the number of arrows that can be shot. An arrow once shot keeps travelling up infinitely. The problem is to find the minimum number of arrows that must be shot to burst all balloons. Example: Input: [[10,16], [2,8], [1,6], [7,12]] Output: 2 Explanation: One way is to shoot one arrow for example at x = 6 (bursting the balloons [2,8] and [1,6]) and another arrow at x = 11 (bursting the other two balloons).

贪婪算法来做的题,因为局部最优解就等于全局最优解 [Mine]排序,在第一区间射一箭,找到能爆的最大end,然后在未爆的第一区间,再射一箭。 [Mine]箭没有一定要射在重叠区域,只要能连锁爆炸就行

[LeetCode#495] Teemo Attacking 提莫攻击 In LLP world, there is a hero called Teemo and his attacking can make his enemy Ashe be in poisoned condition. Now, given the Teemo's attacking ascending time series towards Ashe and the poisoning time duration per Teemo's attacking, you need to output the total time that Ashe is in poisoned condition. You may assume that Teemo attacks at the very beginning of a specific time point, and makes Ashe be in poisoned condition immediately. Example 1: Input: [1,4], 2 Output: 4 Explanation: At time point 1, Teemo starts attacking Ashe and makes Ashe be poisoned immediately. This poisoned status will last 2 seconds until the end of time point 2. And at time point 4, Teemo attacks Ashe again, and causes Ashe to be in poisoned status for another 2 seconds. So you finally need to output 4. Example 2: Input: [1,2], 2 Output: 3 Explanation: At time point 1, Teemo starts attacking Ashe and makes Ashe be poisoned. This poisoned status will last 2 seconds until the end of time point 2. However, at the beginning of time point 2, Teemo attacks Ashe again who is already in poisoned status. Since the poisoned status won't add up together, though the second poisoning attack will still work at time point 2, it will stop at the end of time point 3. So you finally need to output 3. Note: You may assume the length of given time series array won't exceed 10000. You may assume the numbers in the Teemo's attacking time series and his poisoning time duration per attacking are non-negative integers, which won't exceed 10,000,000.

贪心算法,比较相邻两个时间点的时间差,如果小于duration,就加上这个差,如果大于或等于,就加上duration即可

[LeetCode#490] The Maze 迷宫 There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolling up, down, left or right, but it won't stop rolling until hitting a wall. When the ball stops, it could choose the next direction. Given the ball's start position, the destination and the maze, determine whether the ball could stop at the destination. The maze is represented by a binary 2D array. 1 means the wall and 0 means the empty space. You may assume that the borders of the maze are all walls. The start and destination coordinates are represented by row and column indexes. Example 1 Input 1: a maze represented by a 2D array 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 1 0 0 0 0 0 Input 2: start coordinate (rowStart, colStart) = (0, 4) Input 3: destination coordinate (rowDest, colDest) = (4, 4) Output: true Explanation: One possible way is : left -> down -> left -> down -> right -> down -> right. Example 2 Input 1: a maze represented by a 2D array 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 1 0 0 0 0 0 Input 2: start coordinate (rowStart, colStart) = (0, 4) Input 3: destination coordinate (rowDest, colDest) = (3, 2) Output: false Explanation: There is no way for the ball to stop at the destination. Note: There is only one ball and one destination in the maze. Both the ball and the destination exist on an empty space, and they will not be at the same position initially. The given maze does not contain border (like the red rectangle in the example pictures), but you could assume the border of the maze are all walls. The maze contains at least 2 empty spaces, and both the width and height of the maze won't exceed 100.

这次迷宫是有一个滚动的小球,这样就不是每次只走一步了,而是朝某一个方向一直滚,直到遇到墙或者边缘才停下来,问小球是否可以停在目的地 [Mine]目的地必定至少有一边是墙,球砸向墙壁,停下来 #1 DFS+memory #1 BFS+queue

[LeetCode#442] Find All Duplicates in an Array 找出数组中所有重复项 Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once. Find all the elements that appear twice in this array. Could you do it without extra space and in O(n) runtime? Example: Input: [4,3,2,7,8,2,3,1] Output: [2,3]

这类问题的核心是就是找nums[i]和nums[nums[i] - 1]的关系 #1 对于每个nums[i],我们将其对应的nums[nums[i] - 1]取相反数,如果其已经是负数了,说明之前存在过,我们将其加入结果res中即可 #2 将nums[i]置换到其对应的位置nums[nums[i]-1]上去.我们最后在对应位置检验,如果nums[i]和i+1不等,那么我们将nums[i]存入结果res中即可 #3 在nums[nums[i]-1]位置累加数组长度n,最后要找出现两次的数只需要看nums[i]的值是否大于2n即可 [Mine]想尽办法在nums[nums[i] - 1]上做标记(负数啦,index和value不match啦,+n越界啦)

[LeetCode#473] Matchsticks to Square 火柴棍组成正方形 Remember the story of Little Match Girl? By now, you know exactly what matchsticks the little match girl has, please find out a way you can make one square by using up all those matchsticks. You should not break any stick, but you can link them up, and each matchstick must be used exactly one time. Your input will be several matchsticks the girl has, represented with their stick length. Your output will either be true or false, to represent whether you could make one square using all the matchsticks the little match girl has. Example 1: Input: [1,1,2,2,2] Output: true Explanation: You can form a square with length 2, one side of the square came two sticks with length 1. Example 2: Input: [3,3,3,3,4] Output: false Explanation: You cannot find a way to form a square with all the matchsticks. Note: The length sum of the given matchsticks is in the range of 0 to 10^9. The length of the given matchstick array will not exceed 15.

这道题实际上是让我们将一个数组分成四个和相等的子数组 #1 优化过的递归来解 DFS+ 数组从大到小的顺序排序,这样大的数字先加,如果超过target了,就直接跳过了后面的再次调用递归的操作 [Mine]把数字放在各个边试试,和已有边上的相加,超过target的,跳过;找不到任何可以放入的方案,忽略;找到恰好填满四边的方案,成功。 num[0]放在sum[0]上试试,DPS..... num[0]放在sum[1]上试试,DPS..... 四叉树 #2 迭代 一个变量all,初始化为(1 << n) - 1,这是什么意思呢,all其实是一个mask,数组中有多少个数字,all就有多少个1 两个一维数组masks和validHalf,其中masks保存和target相等的几个数字位置的mask,validHalf保存某个mask是否是总和的一半 [Mine]用all来计算各种数组组合的sum,如果等于target,它就是一个备选的边,存入masks。 如果找到两个无共同数字的mask,那么half = mask1 | mask2 就可以组成双边方案,存在validHalf,如果validHalf[all ^ half]也恰巧是true,说明剩余的数字也可以组成一个双边方案,这就是四边方案 思路和#416 Partition Equal Subset Sum不一样,#416是平分两份,这里是平分四份。#416只要找到一次target就行,这里需要找到至少三次互无交集的target组合 所以要么DPS+sort,穷举各种组合。 要么利用bitmap记录可以组成target的备选方案,利用bitmap操作找到互无交集的四个方案。

[LeetCode#502] IPO 上市 Suppose LeetCode will start its IPO soon. In order to sell a good price of its shares to Venture Capital, LeetCode would like to work on some projects to increase its capital before the IPO. Since it has limited resources, it can only finish at most k distinct projects before the IPO. Help LeetCode design the best way to maximize its total capital after finishing at most k distinct projects. You are given several projects. For each project i, it has a pure profit Pi and a minimum capital of Ci is needed to start the corresponding project. Initially, you have W capital. When you finish a project, you will obtain its pure profit and the profit will be added to your total capital. To sum up, pick a list of at most k distinct projects from given projects to maximize your final capital, and output your final maximized capital. Example 1: Input: k=2, W=0, Profits=[1,2,3], Capital=[0,1,1]. Output: 4 Explanation: Since your initial capital is 0, you can only start the project indexed 0. After finishing it you will obtain profit 1 and your capital becomes 1. With capital 1, you can either start the project indexed 1 or the project indexed 2. Since you can choose at most 2 projects, you need to finish the project indexed 2 to get the maximum capital. Therefore, output the final maximized capital, which is 0 + 1 + 3 = 4. Note: You may assume all numbers in the input are non-negative integers. The length of Profits array and Capital array will not exceed 50,000. The answer is guaranteed to fit in a 32-bit signed integer.

这道题说初始时我们的资本为0,可以交易k次,并且给了我们提供了交易所需的资本和所能获得的利润,让我们求怎样选择k次交易,使我们最终的资本最大。 #1 用贪婪算法来解,每一次都选择资本范围内最大利润的进行交易,那么我们首先应该建立资本和利润对,然后根据资本的大小进行排序,然后我们根据自己当前的资本,用二分搜索法在有序数组中找第一个大于当前资本的交易的位置,然后往前退一步就是最后一个不大于当前资本的交易,然后向前遍历,找到利润最大的那个的进行交易,把利润加入资本W中,然后将这个交易对删除,这样我们就可以保证在进行k次交易后,我们的总资本最大 #2 贪婪算法 资本利润对放在最小堆中,取出小于当前资本的,然后利润资本存入最大堆中

[LeetCode#404] Sum of Left Leaves 左子叶之和 Find the sum of all left leaves in a given binary tree. Example: 3 / \ 9 20 / \ 15 7 There are two left leaves in the binary tree, with values 9 and 15 respectively. Return 24.

遍历 当前结点是否是左子节点,如果是左子节点,而且该左子节点再没有子节点了说明其是左子叶,那么我们将其值加入结果res中

[LeetCode#422] Valid Word Square 验证单词平方 Given a sequence of words, check whether it forms a valid word square. A sequence of words forms a valid word square if the kth row and column read the exact same string, where 0 ≤k < max(numRows, numColumns). Note: The number of words given is at least 1 and does not exceed 500. Word length will be at least 1 and does not exceed 500. Each word contains only lowercase English alphabet a-z. Example 1: Input: [ "abcd", "bnrt", "crmy", "dtye" ] Output: true Explanation: The first row and first column both read "abcd". The second row and second column both read "bnrt". The third row and third column both read "crmy". The fourth row and fourth column both read "dtye". Therefore, it is a valid word square. Example 2: Input: [ "abcd", "bnrt", "crm", "dt" ] Output: true Explanation: The first row and first column both read "abcd". The second row and second column both read "bnrt". The third row and third column both read "crm". The fourth row and fourth column both read "dt". Therefore, it is a valid word square. Example 3: Input: [ "ball", "area", "read", "lady" ] Output: false Explanation: The third row reads "read" while the third column reads "lead". Therefore, it is NOT a valid word square.

遍历二维数组,然后验证对应位上的字符是否相等的问题

[LeetCode#407] Trapping Rain Water II 收集雨水之二 Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevation map, compute the volume of water it is able to trap after raining. Note: Both m and n are less than 110. The height of each unit cell is greater than 0 and is less than 20,000. Example: Given the following 3x6 height map: [ [1,4,3,1,3,2], [3,2,1,3,2,4], [2,3,3,2,3,1] ] Return 4.

采用模拟海平面上升的方法来做,我们维护一个海平面高度mx,初始化为最小值,从1开始往上升,那么我们BFS遍历的时候就需要从高度最小的格子开始遍历,那么我们的queue就不能使用普通队列了,而是使用优先级队列,将高度小的放在队首,最先取出(小堆),抬高水面,在not visited块中找洼地。 [Mine]不断涨水,Visited标记表明这块上不可能有水。所以初始化边上的块都是visited。随着水涨,从visited 小堆中向内BSF,高于水面的只入堆,标visited。低于水面的,水可灌入,由于一定是从最短边BSF发现的,所以可以达到的水面高度一定是mx-hight[i][j]。 [Mine]技术:最小堆,BFS;先把桶壁圈出,从小堆中取值,作为水面,淹没一个块,BFS这个块,如果发现比水面高的,就是新的桶壁,入堆,发现比水面低的,保持水面不动,用BSF寻找洼地旁的洼地,并计算蓄水量。此水面能灌入的洼地都计算后(visited),再冲小堆中取下一个可以掩埋的块。 这是将模具浸入水中的过程,不是下雨的过程。

[LeetCode#444] Sequence Reconstruction 序列重建 Check whether the original sequence org can be uniquely reconstructed from the sequences in seqs. The org sequence is a permutation of the integers from 1 to n, with 1 ≤ n ≤ 104. Reconstruction means building a shortest common supersequence of the sequences in seqs (i.e., a shortest sequence so that all sequences in seqs are subsequences of it). Determine whether there is only one sequence that can be reconstructed from seqs and it is the org sequence. Example 1: Input: org: [1,2,3], seqs: [[1,2],[1,3]] Output: false Explanation: [1,2,3] is not the only one sequence that can be reconstructed, because [1,3,2] is also a valid sequence that can be reconstructed. Example 2: Input: org: [1,2,3], seqs: [[1,2]] Output: false Explanation: The reconstructed sequence can only be [1,2]. Example 3: Input: org: [1,2,3], seqs: [[1,2],[1,3],[2,3]] Output: true Explanation: The sequences [1,2], [1,3], and [2,3] can uniquely reconstruct the original sequence [1,2,3]. Example 4: Input: org: [4,1,5,2,6,3], seqs: [[5,2,6,3],[4,1,5,2]] Output: true

问这些子序列能否唯一的重建出原序列。能唯一重建的意思就是任意两个数字的顺序必须是一致的 #1 用了一个一维数组pos来记录org中每个数字对应的位置 int n = org.size() for (int i = 0; i < n; ++i) pos[org[i]] = i; 对每一个seq[i - 1], seq[i],检查其是否match org中的顺序。如果seq[i - 1]和 seq[i]在org也是相邻关系,说明字符seq[i]在org中已经被确认了。 #2 用两个哈希表, 其中m为数字和其位置之间的映射,pre为当前数字和其前一个位置的数字在org中的位置之间的映射, 当遍历到某一个数字的时候,我们看当前数字是否在pre中有映射,如果没有的话,我们建立该映射,注意如果是第一个位置的数字的话,其前面数字设为-1。如果该映射存在的话,我们对比前一位数字在org中的位置和当前的映射值的大小,取其中较大值。最后我们遍历一遍org,看每个数字的映射值是否是前一个数字的位置,如果有不是的返回false,全部验证成功返回true [Mine]org中每一个字符及其前面的字符的顺序都是在seqs中有明确指示的。 每个org的字符都可以在seq中找到其确定的前字符。 Att: 如果seq[i - 1]和 seq[i]在org也是相邻关系,说明字符seq[i]在org中已经被确认了。

[LeetCode#406] Queue Reconstruction by Height 根据高度重建队列 Suppose you have a random list of people standing in a queue. Each person is described by a pair of integers(h, k), where h is the height of the person and k is the number of people in front of this person who have a height greater than or equal to h. Write an algorithm to reconstruct the queue. Note: The number of people is less than 1,100. Example Input: [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] Output: [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]

队列中的每个元素是一个pair,分别为身高和前面身高不低于当前身高的人的个数,让我们重新排列队列,使得每个pair的第二个参数都满足题意 #1 首先我们给队列先排个序,按照身高高的排前面,如果身高相同,则第二个数小的排前面。然后我们新建一个空的数组,遍历之前排好序的数组,然后根据每个元素的第二个数字,将其插入到res数组中对应的位置 [Mine]每个pair第二个数是比它高或一样高的人的相对位置。身高倒序插入,使这样的相对位置是直接确定的。 [Mine]身高倒序保证,已经排好的人一定比要加入的人高(或相等),用插入点来保证pair.second。后加入的人无论插入到哪里都不破坏已有pair的正确性 #2 如#1排序好后,通过一个变量cnt和k的关系来将元素向前移动到正确位置,移动到方法是通过每次跟前面的元素交换位置 [Mine]相当于身高倒序后,再用pair.second,做冒泡排序调整。

[LeetCode#420] Strong Password Checker 密码强度检查器 A password is considered strong if below conditions are all met: It has at least 6 characters and at most 20 characters. It must contain at least one lowercase letter, at least one uppercase letter, and at least one digit. It must NOT contain three repeating characters in a row ("...aaa..." is weak, but "...aa...a..." is strong, assuming other conditions are met). Write a function strongPasswordChecker(s), that takes a string s as input, and return the MINIMUM change required to make s a strong password. If s is already strong, return 0. Insertion, deletion or replace of any one character are all considered as one change.

非强密码串主要有的三个问题: 1. 长度问题 2. 缺失字符或数字 3. 重复字符 我们的目标就是尽可能的找出这种能解决多种问题的操作。由于情况三(重复字符)可以用三种操作来解决,所以我们分别来看能同时解决情况一和情况三,跟同时解决情况二和情况三的操作。 1. 当密码串长度小于6时,情况一和情况二的操作步骤可以完全覆盖情况三 2. 当密码串长度大于等于6个的时候,我们尽量不要用插入字符操作,因为这有可能会使长度超过限制。 3. 在解决情况三的时候还要综合考虑到情况一(超长时)。对于重复字符个数k大于等于3的情况,我们并不是直接将其删除到2个,而是先将其删除到最近的(3m+2)个,那么如果k正好被3整除,那么我们直接变为k-1,如果k除以3余1,那么变为k-2。这样做的好处是3m+2个重复字符可以最高效的用替换m个字符来去除重复。 [Mine]分支较多,综合考虑各种情况


संबंधित स्टडी सेट्स

Unit 6 Vocabulary Definitions - Level E

View Set

Science 906 self test 1 study guide

View Set

Chapter 8: Thermochemistry Problems

View Set

Chapter 45 Assessment and Management of Patients with Endocrine Disorders

View Set

AWT Technical Reference Manual: Chapter 1 Questions

View Set