喜刷刷4

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

[LeetCode#674] Longest Continuous Increasing Subsequence 最长连续递增序列 Given an unsorted array of integers, find the length of longest continuous increasing subsequence. Example 1: Input: [1,3,5,4,7] Output: 3 Explanation: The longest continuous increasing subsequence is [1,3,5], its length is 3. Even though [1,3,5,7] is also an increasing subsequence, it's not a continuous one where 5 and 7 are separated by 4. Example 2: Input: [2,2,2,2,2] Output: 1 Explanation: The longest continuous increasing subsequence is [2], its length is 1. Note: Length of the array will not exceed 10,000.

Not DP just O(n) for (int num : nums) { if (num > cur) ++cnt; else cnt = 1; res = max(res, cnt); cur = num; }

[LeetCode#713] Subarray Product Less Than K 子数组乘积小于K Your are given an array of positive integers nums. Count and print the number of (contiguous) subarrays where the product of all the elements in the subarray is less than k. Example 1: Input: nums = [10, 5, 2, 6], k = 100 Output: 8 Explanation: The 8 subarrays that have product less than 100 are: [10], [5], [2], [6], [10, 5], [5, 2], [2, 6], [5, 2, 6]. Note that [10, 5, 2] is not included as the product of 100 is not strictly less than k. Note: 0 < nums.length <= 50000. 0 < nums[i] < 1000. 0 <= k < 10^6.

一个数组和一个数字K,让我们求子数组且满足乘积小于K的个数。 #1 滑动窗口: 维护一个数字乘积刚好小于k的滑动窗口窗口 滑动窗口的左边界需要向右移动一位,删除最左边的数字,那么少了一个数字,乘积就会改变,所以用prod除以最左边的数字,然后左边右移一位,即left自增1

[LeetCode#625] Minimum Factorization 最小因数分解 Given a positive integer a, find the smallest positive integer b whose multiplication of each digit equals to a. If there is no answer or the answer is not fit in 32-bit signed integer, then return 0. Example 1 Input: 48 Output: 68 Example 2 Input: 15 Output: 35

因数分解,让我们找出因数组成的最小的数字。 分解出的因数一定是个位数字,即范围是[2, 9]。那我们就可以从大到小开始找因数 首先查找9是否是因数,是要能整除a,就是其因数,如果是的话,就加入到结果res的开头,a自除以9,我们用while循环查找9,直到取出所有的9,然后取8,7,6...以此类推 注意越界检查

[LeetCode#629] K Inverse Pairs Array K个翻转对数组 Given two integers n and k, find how many different arrays consist of numbers from 1 to n such that there are exactly k inverse pairs. We define an inverse pair as following: For ith and jth element in the array, if i < j and a[i] > a[j] then it's an inverse pair; Otherwise, it's not. Since the answer may very large, the answer should be modulo 109 + 7. Example 1: Input: n = 3, k = 0 Output: 1 Explanation: Only the array [1,2,3] which consists of numbers from 1 to 3 has exactly 0 inverse pair. Example 2: Input: n = 3, k = 1 Output: 2 Explanation: The array [1,3,2] and [2,1,3] have exactly 1 inverse pair. Note: The integer n is in the range [1, 1000] and k is in the range [0, 1000].

给了我们1到n总共n个数字,让我们任意排列数组的顺序,使其刚好存在k个翻转对,所谓的翻转对,就是位置在前面的数字值大,而且题目中表明了结果会很大很大,要我们对一个很大的数字取余。 对于这种结果巨大的题目,劝君放弃暴力破解或者是无脑递归,想都不用想,那么最先应该考虑的就是DP的解法了。 二维的DP数组,其中dp[i][j]表示1到i的数字中有j个翻转对的排列总数,那么我们要求的就是dp[n][k]了 这里xxxx表示1到4的任意排列,那么第一种情况xxxx5不会增加任何新的翻转对,因为xxxx中没有比5大的数字,而 xxx5x会新增加1个翻转对,xx5xx,x5xxx,5xxxx分别会增加2,3,4个翻转对。那么xxxx5就相当于dp[n][k],即dp[4][k],那么依次往前类推,就是dp[n][k-1], dp[n][k-2]...dp[n][k-n] dp[n][k] = dp[n - 1][k] + dp[n - 1][k-1] + ... + dp[n - 1][k - n + 1] 我们可以对上面的解法进行时间上的优化,还是来看我们的递推公式: dp[n][k] = dp[n - 1][k] + dp[n - 1][k-1] + ... + dp[n - 1][k - n + 1] 我们可以用k+1代替k,得到: dp[n][k+1] = dp[n - 1][k+1] + dp[n - 1][k] + ... + dp[n - 1][k + 1 - n + 1] 用第二个等式减去第一个等式可以得到: dp[n][k+1] = dp[n][k] + dp[n - 1][k+1] - dp[n - 1][k - n + 1] 将k+1换回成k,可以得到: dp[n][k] = dp[n][k-1] + dp[n - 1][k] - dp[n - 1][k - n] 我们可以发现当k>=n的时候,最后一项的数组坐标才能为非负数,从而最后一项才有值,所以我们再更新的时候只需要判断一下k和n的关系,如果k>=n的话,就要减去最后一项, dp[0][0] = 1; for (int i = 1; i <= n; ++i) { dp[i][0] = 1; for (int j = 1; j <= k; ++j) { dp[i][j] = (dp[i - 1][j] + dp[i][j - 1]) % M; if (j >= i) { dp[i][j] = (dp[i][j] - dp[i - 1][j - i] + M) % M; } } } [Mine]类似:#634 Find the Derangement of An Array

[LeetCode#688] Knight Probability in Chessboard 棋盘上骑士的可能性 On an NxN chessboard, a knight starts at the r-th row and c-th column and attempts to make exactly K moves. The rows and columns are 0 indexed, so the top-left square is (0, 0), and the bottom-right square is (N-1, N-1). A chess knight has 8 possible moves it can make, as illustrated below. Each move is two squares in a cardinal direction, then one square in an orthogonal direction. Each time the knight is to move, it chooses one of eight possible moves uniformly at random (even if the piece would go off the chessboard) and moves there. The knight continues moving until it has made exactly K moves or has moved off the chessboard. Return the probability that the knight remains on the board after it has stopped moving. Example: Input: 3, 2, 0, 0 Output: 0.0625 Explanation: There are two moves (to (1,2), (2,1)) that will keep the knight on the board. From each of those positions, there are also two moves that will keep the knight on the board. The total probability the knight stays on the board is 0.0625. Note: N will be between 1 and 25. K will be between 0 and 100. The knight always initially starts on the board.

给了我们一个起始位置,然后说允许我们走K步,问走完K步之后还能留在棋盘上的概率是多少。 分子是走完K步还在棋盘上的走法,分母是没有限制条件的总共的走法。 分母:K步就是8的K次方 如果BFS, TLE #1 DP 实际上应该用三维dp[k][i][j],但如果用一个临时的二维数组,可以减为二维dp。 dp[i][j]表示在棋盘(i, j)位置上走完当前步骤还留在棋盘上的走法总和,初始化为1 刷新整个棋盘K次,每次先做临时all zero二维数组t,对每个(i, j)为起跳点,将有效的落点dp值(上一步,由此点出发的走法总和)累加到t[i][j]上。然后用t覆盖dp #2 DFS+Memo (三维Memo[k][i][j]) K->1,八个方向,DFS

[LeetCode#657] Judge Route Circle 判断路线绕圈 Initially, there is a Robot at position (0, 0). Given a sequence of its moves, judge if this robot makes a circle, which means it moves back to the original place. The move sequence is represented by a string. And each move is represent by a character. The valid robot moves are R (Right), L(Left), U (Up) and D (down). The output should be true or false representing whether the robot makes a circle. Example 1: Input: "UD" Output: true Example 2: Input: "LL" Output: false

让我们判断一个路径是否绕圈,就是说有多少个U,就得对应多少个D。同理,L和R的个数也得相等。 #1 如果是U,则cnt1自增1;如果是D,cnt1自减1。同理,如果是L,则cnt1自增1;如果是R,cnt1自减1。最后只要看cnt1和cnt2是否同时为0即可 #2 哈希表来建立字符和其出现的次数之间的映射,最后直接比较对应的字符出现的次数是否相等即可

[LeetCode#645] Set Mismatch 设置不匹配 The set S originally contains numbers from 1 to n. But unfortunately, due to the data error, one of the numbers in the set got duplicated to another number in the set, which results in repetition of one number and loss of another number. Given an array nums representing the data status of this set after the error. Your task is to firstly find the number occurs twice and then find the number that is missing. Return them in the form of an array. Example 1: Input: nums = [1,2,2,4] Output: [2,3] Note: The given array size will in the range [2, 10000]. The given array's numbers won't have any order.

#1 统计每个数字出现的次数了,然后再遍历次数数组,如果某个数字出现了两次就是重复数,如果出现了0次,就是缺失数 #2 遍历每个数字,然后将其应该出现的位置上的数字变为其相反数,这样如果我们再变为其相反数之前已经成负数了,说明该数字是重复数,将其将入结果res中,然后再遍历原数组,如果某个位置上的数字为正数,说明该位置对应的数字没有出现过,加入res中即可 #3 把乱序的数字放到其正确的位置上,用while循环来不停的放,直到该数字在正确的位置上,那么一旦数组有序了,我们只要从头遍历就能直接找到重复的数字,然后缺失的数字同样也就知道了

[LeetCode#673] Number of Longest Increasing Subsequence 最长递增序列的个数 Given an unsorted array of integers, find the number of longest increasing subsequence. Example 1: Input: [1,3,5,4,7] Output: 2 Explanation: The two longest increasing subsequence are [1, 3, 4, 7] and [1, 3, 5, 7]. Example 2: Input: [2,2,2,2,2] Output: 5 Explanation: The length of longest continuous increasing subsequence is 1, and there are 5 subsequences' length is 1, so output 5. Note: Length of the given array will be not exceed 2000 and the answer is guaranteed to be fit in 32-bit signed int.

DP dp[i]表示以nums[i]为结尾的递推序列的长度,用于计算LIS cnt[i]定义为以nums[i]为结尾的LIS的个数 final, mx=max(dp[i]), ret = sum(cnt[i] if dp[i]=mx) [Mine]LIS + number of LIS for each num[i]

[LeetCode#642] Design Search Autocomplete System 设计搜索自动补全系统 Design a search autocomplete system for a search engine. Users may input a sentence (at least one word and end with a special character '#'). For each character they type except '#', you need to return the top 3historical hot sentences that have prefix the same as the part of sentence already typed. Here are the specific rules: The hot degree for a sentence is defined as the number of times a user typed the exactly same sentence before. The returned top 3 hot sentences should be sorted by hot degree (The first is the hottest one). If several sentences have the same degree of hot, you need to use ASCII-code order (smaller one appears first). If less than 3 hot sentences exist, then just return as many as you can. When the input is a special character, it means the sentence ends, and in this case, you need to return an empty list. Your job is to implement the following functions: The constructor function: AutocompleteSystem(String[] sentences, int[] times): This is the constructor. The input is historical data. Sentences is a string array consists of previously typed sentences. Times is the corresponding times a sentence has been typed. Your system should record these historical data. Now, the user wants to input a new sentence. The following function will provide the next character the user types: List<String> input(char c): The input c is the next character typed by the user. The character will only be lower-case letters ('a' to 'z'), blank space (' ') or a special character ('#'). Also, the previously typed sentence should be recorded in your system. The output will be the top 3 historical hot sentences that have prefix the same as the part of sentence already typed. Example: Operation: AutocompleteSystem(["i love you", "island","ironman", "i love leetcode"], [5,3,2,2]) The system have already tracked down the following sentences and their corresponding times: "i love you" : 5 times "island" : 3 times "ironman" : 2 times "i love leetcode" : 2 times Now, the user begins another search: Operation: input('i') Output: ["i love you", "island","i love leetcode"] Explanation: There are four sentences that have prefix "i". Among them, "ironman" and "i love leetcode" have same hot degree. Since ' ' has ASCII code 32 and 'r' has ASCII code 114, "i love leetcode" should be in front of "ironman". Also we only need to output top 3 hot sentences, so "ironman" will be ignored. Operation: input(' ') Output: ["i love you","i love leetcode"] Explanation: There are only two sentences that have prefix "i ". Operation: input('a') Output: [] Explanation: There are no sentences that have prefix "i a". Operation: input('#') Output: [] Explanation: The user finished the input, the sentence "i a" should be saved as a historical sentence in system. And the following input will be counted as a new search. Note: The input sentence will always start with a letter and end with '#', and only one blank space will exist between two words. The number of complete sentences that to be searched won't exceed 100. The length of each sentence including those in the historical data won't exceed 100. Please use double-quote instead of single-quote when you write test cases even for a character input. Please remember to RESET your class variables declared in class AutocompleteSystem, as static/class variables are persisted across multiple test cases. Please see here for more details.

Hashmap+堆 哈希map,建立句子和其出现频率的映射 包含data前缀的前三高频句子了,我们使用优先队列来做

[LeetCode#691] Stickers to Spell Word 贴片拼单词 We are given N different types of stickers. Each sticker has a lowercase English word on it. You would like to spell out the given target string by cutting individual letters from your collection of stickers and rearranging them. You can use each sticker more than once if you want, and you have infinite quantities of each sticker. What is the minimum number of stickers that you need to spell out the target? If the task is impossible, return -1. Example 1: Input: ["with", "example", "science"], "thehat" Output: 3 Explanation: We can use 2 "with" stickers, and 1 "example" sticker. After cutting and rearrange the letters of those stickers, we can form the target "thehat". Also, this is the minimum number of stickers necessary to form the target string. Example 2: Input: ["notice", "possible"], "basicbasic" Output: -1 Explanation: We can't form the target "basicbasic" from cutting letters from the given stickers. Note: stickers has length in the range [1, 50]. stickers consists of lowercase English words (without apostrophes). target has length in the range [1, 15], and consists of lowercase English letters. In all test cases, all words were chosen randomly from the 1000 most common US English words, and the target was chosen as a concatenation of two random words. The time limit may be more challenging than usual. It is expected that a 50 sticker test case can be solved within 35ms on average.

N个贴片,每个贴片上有一个小写字母的单词,给了我们一个目标单词target,让我们通过剪下贴片单词上的字母来拼出目标值,每个贴片都有无数个,问我们最少用几个贴片能拼出目标值target,如果不能拼出来的话,就返回-1。 #1 DP dp[i]表示组成第i个子集合所需要的最少的sticker的个数,注意这里是子集合,而不是子串。长度为n的字符串共有2的n次方个子集合 index i 的二进制就是子集合中字符出现的掩码。 最终答案就是dp最后一个,全1 index的结果。 二进制化DP 两层循环,一层是i,遍历二进制化的集合子集。 二层是遍历各个sticker when i=0,找第一个sticker对target match的mask(cur),dp[cur] = min(dp[cur], dp[i] + 1); [=1] 找第二个sticker对target match的mask(cur),同样dp更新。。。。 外循环遍历各个子集。 这样不同子集i基础上,只叠加上一个sticker,可以逼近target的子集状态cur,取dp[cur]和dp[i] + 1较小者 [Mine]将All Zero到All one中二进制分出子状态,每个sticker的match result都有可能向target推进,目标是转移次数最少的方案。 [Mine]虽然每个sticker可以无限使用,但每使用一次使用的贴片总数就增加,所以还是要一一匹配 [Mine]多重背包?个人认为不是很像,其实DFS+Memo可能更容易想到,穷举各种可能的组合,并Memo。使用二进制化进行优美的DP,更难想到。 #2 DFS+Memo 不用二进制化子集,可以自组字符串做Memo的key,value为拼出目标字符串(每层递归不同)的最少sticker数。 可以维护一个匹配当前target的freq数组,用来加速和各个sticker的匹配

[LeetCode#653] Two Sum IV - Input is a BST 两数之和之四 - 输入是二叉搜索树 Given a Binary Search Tree and a target number, return true if there exist two elements in the BST such that their sum is equal to the given target. Example 1: Input: 5 / \ 3 6 / \ \ 2 4 7 Target = 9 Output: True Example 2: Input: 5 / \ 3 6 / \ \ 2 4 7 Target = 28 Output: False

Two sum:把数组变成了一棵二叉树而已 遍历+hashset

[LeetCode#683] K Empty Slots K个空槽 There is a garden with N slots. In each slot, there is a flower. The N flowers will bloom one by one in N days. In each day, there will be exactly one flower blooming and it will be in the status of blooming since then. Given an array flowers consists of number from 1 to N. Each number in the array represents the place where the flower will open in that day. For example, flowers[i] = x means that the unique flower that blooms at day i will be at position x, where i and x will be in the range from 1 to N. Also given an integer k, you need to output in which day there exists two flowers in the status of blooming, and also the number of flowers between them is k and these flowers are not blooming. If there isn't such day, output -1. Example 1: Input: flowers: [1,3,2] k: 1 Output: 2 Explanation: In the second day, the first and the third flower have become blooming. Example 2: Input: flowers: [1,2,3] k: 1 Output: -1 Note: The given array will be in the range [1, 20000].

flowers[i] = x表示第i天放的花会在位置x。给了我们一个整数k,让我们判断是否正好有两朵盛开的花中间有k个空槽,如果有,返回当前天数,否则返回-1。 #1 days[i] = t表示在i+1位置上会在第t天放上花。题目就变为找一个k+2大小的子数组,除了首尾两个数字,中间的k个数字都要大于首尾两个数字即可,那么首尾两个数字中较大的数就是当前的天数。 固定大小窗口,找符合条件的left (right=k+1+left) #2 TreeSet来做,利用其自动排序的特点,然后用lower_bound和upper_bound进行快速的二分查找

[LeetCode#696] Count Binary Substrings 统计二进制子字符串 Give a string s, count the number of non-empty (contiguous) substrings that have the same number of 0's and 1's, and all the 0's and all the 1's in these substrings are grouped consecutively. Substrings that occur multiple times are counted the number of times they occur. Example 1: Input: "00110011" Output: 6 Explanation: There are 6 substrings that have equal number of consecutive 1's and 0's: "0011", "01", "1100", "10", "0011", and "01". Notice that some of these substrings repeat and are counted the number of times they occur. Also, "00110011" is not a valid substring because all the 0's (and 1's) are not grouped together. Example 2: Input: "10101" Output: 4 Explanation: There are 4 substrings: "10", "01", "10", "01" that have equal number of consecutive 1's and 0's. Note: s.length will be between 1 and 50,000. s will only consist of "0" or "1" characters.

一个二进制字符串,然后我们统计具有相同0和1的个数,且0和1各自都群组在一起(即0和1不能交替出现)的子字符串的个数 #1 遍历,ones或zeros计数或重置 #2 不用具体的分0和1的情况来讨论了,而是直接用了pre和cur两个变量

[LeetCode#604] Design Compressed String Iterator 设计压缩字符串的迭代器 Design and implement a data structure for a compressed string iterator. It should support the following operations: next and hasNext. The given compressed string will be in the form of each letter followed by a positive integer representing the number of this letter existing in the original uncompressed string. next() - if the original string still has uncompressed characters, return the next letter; Otherwise return a white space. hasNext() - Judge whether there is any letter needs to be uncompressed. Note: Please remember to RESET your class variables declared in StringIterator, as static/class variables are persisted across multiple test cases. Please see here for more details. Example: StringIterator iterator = new StringIterator("L1e2t1C1o1d1e1"); iterator.next(); // return 'L' iterator.next(); // return 'e' iterator.next(); // return 'e' iterator.next(); // return 't' iterator.next(); // return 'C' iterator.next(); // return 'o' iterator.next(); // return 'd' iterator.hasNext(); // return true iterator.next(); // return 'e' iterator.hasNext(); // return false iterator.next(); // return ' '

一个压缩字符串,就是每个字符后面跟上其出现的次数,这里就算只出现一次,后面还是要加上1 取出每个字符和其出现的次数,每当调用一次next,次数减1,如果减到0了,我们就要取出下一个字符和其出现的次数。

[LeetCode#720] Longest Word in Dictionary 字典中的最长单词 Given a list of strings words representing an English Dictionary, find the longest word in words that can be built one character at a time by other words in words. If there is more than one possible answer, return the longest word with the smallest lexicographical order. If there is no answer, return the empty string. Example 1: Input: words = ["w","wo","wor","worl", "world"] Output: "world" Explanation: The word "world" can be built one character at a time by "w", "wo", "wor", and "worl". Example 2: Input: words = ["a", "banana", "app", "appl", "ap", "apply", "apple"] Output: "apple" Explanation: Both "apply" and "apple" can be built from other words in the dictionary. However, "apple" is lexicographically smaller than "apply". Note: All the strings in the input will only contain lowercase letters. The length of words will be in the range [1, 1000]. The length of words[i] will be in the range [1, 30].

一个字典,是个字符串数组,然后问我们从单个字符开始拼,最长能组成啥单词,注意中间生成的字符串也要在字典中存在,而且当组成的单词长度相等时,返回字母顺序小的那个。 #1 利用集合,从长度为1的单词开始,尝试增加一个字符(26个字母)BFS或DFS #2 给数组排个序,就可以使用贪婪算法 长度为1,说明是起始单词,不需要的多余的判断,否则的话就要判断其去掉最后一个字母后的单词是否在集合中存在(因为字母顺序排序过,如果不存在就说明断了)

[LeetCode#647] Palindromic Substrings 回文子字符串 Given a string, your task is to count how many palindromic substrings in this string. The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters. Example 1: Input: "abc" Output: 3 Explanation: Three palindromic strings: "a", "b", "c". Example 2: Input: "aaa" Output: 6 Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa". Note: The input string length won't exceed 1000.

一个字符串,让我们计算有多少个回文子字符串 #1简单粗暴 以每个点为奇数回文串的中心点计算; 以每个相邻点为偶数回文串中心点计算。 #2 dp[i][j]定义成子字符串[i, j]是否是回文串

[LeetCode#616] Add Bold Tag in String 字符串中增添加粗标签 Given a string s and a list of strings dict, you need to add a closed pair of bold tag <b> and </b> to wrap the substrings in s that exist in dict. If two such substrings overlap, you need to wrap them together by only one pair of closed bold tag. Also, if two substrings wrapped by bold tags are consecutive, you need to combine them. Example 1: Input: s = "abcxyz123" dict = ["abc","123"] Output: "<b>abc</b>xyz<b>123</b>" Example 2: Input: s = "aaabbcc" dict = ["aaa","aab","bc"] Output: "<b>aaabbc</b>c" Note: The given dict won't contain duplicates, and its length won't exceed 100. All the strings in input have length in range [1, 1000].

一个字符串,还有一个字典,让我们把字符串中在字典中的单词加粗,注意如果两个单词有交集或者相接,就放到同一个加粗标签中 暴力搜索就能过,不用KMP #1 建一个和字符串s等长的bold布尔型数组,表示如果该字符在单词里面就为true 遍历字符串s中的每一个字符,把遍历到的每一个字符当作起始位置,我们都匹配一遍字典中的所有单词,如果能匹配上,我们就用i + len来更新end 那么如果i小于end,bold[i]就要赋值为true了。最后我们更新完bold数组了,就再遍历一遍字符串s,如果bold[i]为false,直接将s[i]加入结果res中;如果bold[i]为true,那么我们用while循环来找出所有连续为true的个数,然后在左右两端加上标签 #2 判断每个单词word是否是S的子串,判断的方法就是逐个字符比较,遍历字符串S,找到和word首字符相等的位置,并且比较随后和word等长的子串,如果完全相同,则将子串所有的位置在bold上比较为true [Mine]#1 是for char in s,for(string : dist) #2是for(string : dist), for char in s

[LeetCode#656] Coin Path 硬币路径 Given an array A (index starts at 1) consisting of N integers: A1, A2, ..., AN and an integer B. The integer Bdenotes that from any place (suppose the index is i) in the array A, you can jump to any one of the place in the array A indexed i+1, i+2, ..., i+B if this place can be jumped to. Also, if you step on the index i, you have to pay Ai coins. If Ai is -1, it means you can't jump to the place indexed i in the array. Now, you start from the place indexed 1 in the array A, and your aim is to reach the place indexed N using the minimum coins. You need to return the path of indexes (starting from 1 to N) in the array you should take to get to the place indexed N using minimum coins. If there are multiple paths with the same cost, return the lexicographically smallest such path. If it's not possible to reach the place indexed N then you need to return an empty array. Example 1: Input: [1,2,4,-1,2], 2 Output: [1,3,5] Example 2: Input: [1,2,4,-1,2], 1 Output: [] Note: Path Pa1, Pa2, ..., Pan is lexicographically smaller than Pb1, Pb2, ..., Pbm, if and only if at the first i where Pai and Pbi differ, Pai < Pbi; when no such i exists, then n < m. A1 >= 0. A2, ..., AN (if exist) will in the range of [-1, 100]. Length of A is in the range of [1, 1000]. B is in the range of [1, 100].

一个数组A,又给了我们一个整数B,表示能走的最大步数,数组上的每个数字都是cost值,如果到达某个位置,就要加上该位置上的数字,起始位置是在第一个数字上,目标是到达末尾位置,我们需要让总cost值最小,并输入路径,如果cos相同的话,输出字母顺序小的那个路径。还有就是如果数组上的某个位置为-1的话,表示到达该位置后不能再去下一个位置,而且数组末位置不能为-1。 #1 DP dp[i]是从末尾到位置i的最小cost值 对于每个遍历到的数字,我们都要遍历其上一步可能的位置的dp[j]值来更新当前dp[i]值 这种从后往前遍历的模式得到的路径一定是字母顺序最小的([Mine]最里层循环是正向的,并且cost是小于,不是小于等于,这造成了cost一样时,字母顺序小的被保留) #2 DP 正向跳的话就需要另一个数组len,len[i]表示从开头到达位置i的路径的长度,如果两个路径的cost相同,那么一定是路径长度大的字母顺序小

[LeetCode#698] Partition to K Equal Sum Subsets 分割K个等和的子集 Given an array of integers nums and a positive integer k, find whether it's possible to divide this array into knon-empty subsets whose sums are all equal. Example 1: Input: nums = [4, 3, 2, 3, 5, 2, 1], k = 4 Output: True Explanation: It's possible to divide it into 4 subsets (5), (1, 4), (2,3), (2,3) with equal sums. Note: 1 <= k <= len(nums) <= 16. 0 < nums[i] < 10000.

一个数组nums和一个数字k,问我们该数字能不能分成k个非空子集合,使得每个子集合的和相同。给了k的范围是[1,16],而且数组中的数字都是正数 #1 递归,排列组合,目标totalSum/k [Note]本算法也可以先排序,再在递归时prune #2 数组排序+贪婪(利用数字都是正数,数字累加只会增大不会减小)。长度为k的数组桶v,原数组从大到小,排序+curIndex,替代了visited [Mine]一个数如果加大当前桶,sum>target,那么这个数一定不在当前桶的正确组合中,因为其后加入任何数都不可能sum=target

[LeetCode#643] Maximum Average Subarray I 子数组的最大平均值 Given an array consisting of n integers, find the contiguous subarray of given length k that has the maximum average value. And you need to output the maximum average value. Example 1: Input: [1,12,-5,-6,50,3], k = 4 Output: 12.75 Explanation: Maximum average is (12-5-6+50)/4 = 51/4 = 12.75 Note: 1 <= k <= n <= 30,000. Elements of the given array will be in the range [-10,000, 10,000].

一个数组nums,还有一个数字k,让我们找长度为k且平均值最大的子数组。由于子数组必须是连续的 #1 整体累加和,计算各个k长区间 #2 滑动窗口,加减sum

[LeetCode#654] Maximum Binary Tree 最大二叉树 Given an integer array with no duplicates. A maximum tree building on this array is defined as follow: The root is the maximum number in the array. The left subtree is the maximum tree constructed from left part subarray divided by the maximum number. The right subtree is the maximum tree constructed from right part subarray divided by the maximum number. Construct the maximum tree by the given array and output the root node of this tree. Example 1: Input: [3,2,1,6,0,5] Output: return the tree root node representing the following tree: 6 / \ 3 5 \ / 2 0 \ 1 Note: The size of the given array will be in the range [1,1000].

一个数组,让我们创建一个最大二叉树,创建规则是数组中的最大值为根结点,然后分隔出的左右部分再分别创建最大二叉树。 #1 递归 用两个变量来指定子数组的范围 #2 辅助数组v,成员为TreeNode,可能为子树根节点。 数组v保持降序。 [Mine]辅助数值造成 1. 自己的左子是自己前面仅小于自己的结点。 2. 自己做自己前面仅大于自己的结点的右子。 扫描到的结点,只关心自己的左子是谁,自己是谁的右子。 降序队列中都是自己前面的结点或子树根节点,对比自己和尾部,将前面仅小于自己的结点挂在自己左子并出队,把自己挂在前面仅大于自己的结点的右子,然后自己入队。

[LeetCode#724] Find Pivot Index 寻找中枢点 Given an array of integers nums, write a method that returns the "pivot" index of this array. We define the pivot index as the index where the sum of the numbers to the left of the index is equal to the sum of the numbers to the right of the index. If no such index exists, we should return -1. If there are multiple pivot indexes, you should return the left-most pivot index. Example 1: Input: nums = [1, 7, 3, 6, 5, 6] Output: 3 Explanation: The sum of the numbers to the left of index 3 (nums[3] = 6) is equal to the sum of numbers to the right of index 3. Also, 3 is the first index where this occurs. Example 2: Input: nums = [1, 2, 3] Output: -1 Explanation: There is no index that satisfies the conditions in the problem statement. Note: The length of nums will be in the range [0, 10000]. Each element nums[i] will be an integer in the range [-1000, 1000].

一个数组,让我们求一个中枢点,使得该位置左右两边的子数组之和相等。 直接遍历,sum

[LeetCode#684] Redundant Connection 冗余的连接 In this problem, a tree is an undirected graph that is connected and has no cycles. The given input is a graph that started as a tree with N nodes (with distinct values 1, 2, ..., N), with one additional edge added. The added edge has two different vertices chosen from 1 to N, and was not an edge that already existed. The resulting graph is given as a 2D-array of edges. Each element of edges is a pair [u, v] with u < v, that represents an undirected edge connecting nodes u and v. Return an edge that can be removed so that the resulting graph is a tree of N nodes. If there are multiple answers, return the answer that occurs last in the given 2D-array. The answer edge [u, v] should be in the same format, with u < v. Example 1: Input: [[1,2], [1,3], [2,3]] Output: [2,3] Explanation: The given undirected graph will be like this: 1 / \ 2 - 3 Example 2: Input: [[1,2], [2,3], [3,4], [1,4], [1,5]] Output: [1,4] Explanation: The given undirected graph will be like this: 5 - 1 - 2 | | 4 - 3 Note: The size of the input 2D-array will be between 3 and 1000. Every integer represented in the 2D-array will be between 1 and N, where N is the size of the input array. Update (2017-09-26): We have overhauled the problem description + test cases and specified clearly the graph is an undirected graph. For the directedgraph follow up please see Redundant Connection II). We apologize for any inconvenience caused.

一个无向图,让我们删掉组成环的最后一条边 #1 邻接表 DFS #2 邻接表 BFS #3 Union Find 并查集 edge连进新node可以,如果edge两段都是相同root的node,就是环了。

[LeetCode#640] Solve the Equation 解方程 Solve a given equation and return the value of x in the form of string "x=#value". The equation contains only '+', '-' operation, the variable x and its coefficient. If there is no solution for the equation, return "No solution". If there are infinite solutions for the equation, return "Infinite solutions". If there is exactly one solution for the equation, we ensure that the value of x is an integer. Example 1: Input: "x+5-3+x=6+x-2" Output: "x=2" Example 2: Input: "x=x" Output: "Infinite solutions" Example 3: Input: "2x=x" Output: "x=0" Example 4: Input: "2x+3x-6x=x+2" Output: "x=-1" Example 5: Input: "x=x+2" Output: "No solution"

一个用字符串表示的方程式,让我们求出x的解,根据例子可知,还包括x有无穷多个解和x没有解的情况。 处理字符串,如何将x的系数合并起来,将常数合并起来,化简成ax=b的形式来求解 先找到等号,然后左右两部分分开处理。由于要化成ax=b的格式,所以左半部分对于x的系数都是加,右半部分对于x的系数都是减。同理,左半部分对于常数是减,右半部分对于常数是加。 int a = 0, b = 0; auto found = equation.find("="); helper(equation.substr(0, found), true, a, b); helper(equation.substr(found + 1), false, a, b); if (a == 0 && a == b) return "Infinite solutions"; if (a == 0 && a != b) return "No solution"; return "x=" + to_string(b / a);

[LeetCode#725] Split Linked List in Parts 拆分链表成部分 Given a (singly) linked list with head node root, write a function to split the linked list into k consecutive linked list "parts". The length of each part should be as equal as possible: no two parts should have a size differing by more than 1. This may lead to some parts being null. The parts should be in order of occurrence in the input list, and parts occurring earlier should always have a size greater than or equal parts occurring later. Return a List of ListNode's representing the linked list parts that are formed. Examples 1->2->3->4, k = 5 // 5 equal parts [ [1], [2], [3], [4], null ] Example 1: Input: root = [1, 2, 3], k = 5 Output: [[1],[2],[3],[],[]] Explanation: The input and each element of the output are ListNodes, not arrays. For example, the input root has root.val = 1, root.next.val = 2, \root.next.next.val = 3, and root.next.next.next = null. The first element output[0] has output[0].val = 1, output[0].next = null. The last element output[4] is null, but it's string representation as a ListNode is []. Example 2: Input: root = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], k = 3 Output: [[1, 2, 3, 4], [5, 6, 7], [8, 9, 10]] Explanation: The input has been split into consecutive parts with size difference at most 1, and earlier parts are a larger size than the later parts. Note: The length of root will be in the range [0, 1000]. Each value of a node in the input will be an integer in the range [0, 999]. k will be an integer in the range [1, 50].

一个链表和一个正数k,让我们分割链表成k部分,尽可能的平均分割。每部分至少一个节点,最多相差一个。如果结点不够了,就用空结点。如果无法平均分,那么多余的结点就按顺序放在子链表中,尽量靠前。 统计链表中结点的总个数,然后除以k,得到的商avg就是能分成的部分个数,余数ext就是包含有多余的结点的子链表的个数。

[LeetCode#655] Print Binary Tree 打印二叉树 Print a binary tree in an m*n 2D string array following these rules: The row number m should be equal to the height of the given binary tree. The column number n should always be an odd number. The root node's value (in string format) should be put in the exactly middle of the first row it can be put. The column and the row where the root node belongs will separate the rest space into two parts (left-bottom part and right-bottom part). You should print the left subtree in the left-bottom part and print the right subtree in the right-bottom part. The left-bottom part and the right-bottom part should have the same size. Even if one subtree is none while the other is not, you don't need to print anything for the none subtree but still need to leave the space as large as that for the other subtree. However, if two subtrees are none, then you don't need to leave space for both of them. Each unused space should contain an empty string "". Print the subtrees following the same rules. Example 1: Input: 1 / 2 Output: [["", "1", ""], ["2", "", ""]] Example 2: Input: 1 / \ 2 3 \ 4 Output: [["", "", "", "1", "", "", ""], ["", "2", "", "", "", "3", ""], ["", "", "4", "", "", "", ""]] Example 3: Input: 1 / \ 2 5 / 3 / 4 Output: [["", "", "", "", "", "", "", "1", "", "", "", "", "", "", ""] ["", "", "", "2", "", "", "", "", "", "", "", "5", "", "", ""] ["", "3", "", "", "", "", "", "", "", "", "", "", "", "", ""] ["4", "", "", "", "", "", "", "", "", "", "", "", "", "", ""]] Note: The height of binary tree is in the range of [1, 10].

一棵二叉树,让我们以数组的形式打印出来。数组每一行的宽度是二叉树的最底层数所能有的最多结点数,存在的结点需要填入到正确的位置上。 最大深度=>宽度:width = (2^height) - 1 每次都在当层子数组的中间,填写根结点。 递归或层序迭代

[LeetCode#723] Candy Crush 糖果消消乐 This question is about implementing a basic elimination algorithm for Candy Crush. Given a 2D integer array board representing the grid of candy, different positive integers board[i][j] represent different types of candies. A value of board[i][j] = 0 represents that the cell at position (i, j) is empty. The given board represents the state of the game following the player's move. Now, you need to restore the board to a stable state by crushing candies according to the following rules: If three or more candies of the same type are adjacent vertically or horizontally, "crush" them all at the same time - these positions become empty. After crushing all candies simultaneously, if an empty space on the board has candies on top of itself, then these candies will drop until they hit a candy or bottom at the same time. (No new candies will drop outside the top boundary.) After the above steps, there may exist more candies that can be crushed. If so, you need to repeat the above steps. If there does not exist more candies that can be crushed (ie. the board is stable), then return the current board. You need to perform the above rules until the board becomes stable, then return the current board. Example 1: Input: board = [[110,5,112,113,114],[210,211,5,213,214],[310,311,3,313,314],[410,411,412,5,414],[5,1,512,3,3],[610,4,1,613,614],[710,1,2,713,714],[810,1,2,1,1],[1,1,2,2,2],[4,1,4,4,1014]] Output: [[0,0,0,0,0],[0,0,0,0,0],[0,0,0,0,0],[110,0,0,0,114],[210,0,0,0,214],[310,0,0,113,314],[410,0,0,213,414],[610,211,112,313,614],[710,311,412,613,714],[810,411,512,713,1014]] Explanation: Note: The length of board will be in the range [3, 50]. The length of board[i] will be in the range [3, 50]. Each board[i][j] will initially start as an integer in the range [1, 2000].

一次消除table中所有可消除的糖果,然后才下落,形成新的table,这样消除后得到的结果就是统一的 只有横向或竖向相同的糖果数达到三个才能消除,并不是所有的连通区域都能消除,所以找连通区域不是一个好办法。 最好的办法其实是每个糖果单独检查其是否能被消除,然后把所有能被删除的糖果都标记出来统一删除,然后在下落糖果,然后再次查找,直到无法找出能够消除的糖果时达到稳定状态。 落处理实际上是把数组中的0都移动到开头,那么就从数组的末尾开始遍历

[LeetCode#690] Employee Importance 员工重要度 You are given a data structure of employee information, which includes the employee's unique id, his importance value and his direct subordinates' id. For example, employee 1 is the leader of employee 2, and employee 2 is the leader of employee 3. They have importance value 15, 10 and 5, respectively. Then employee 1 has a data structure like [1, 15, [2]], and employee 2 has [2, 10, [3]], and employee 3 has [3, 5, []]. Note that although employee 3 is also a subordinate of employee 1, the relationship is not direct. Now given the employee information of a company, and an employee id, you need to return the total importance value of this employee and all his subordinates. Example 1: Input: [[1, 5, [2, 3]], [2, 3, []], [3, 3, []]], 1 Output: 11 Explanation: Employee 1 has importance value 5, and he has two direct subordinates: employee 2 and employee 3. They both have importance value 3. So the total importance value of employee 1 is 5 + 3 + 3 = 11. Note: One employee has at most one direct leader and may have several subordinates. The maximum number of employees won't exceed 2000.

一种员工类,有id,重要度,和direct report的员工,让我们求某个员工的总重要度。 就算某个员工不直接向你汇报工作,而是向你手下人汇报,这个人的重要度也会算进你的重要度中 #1 DFS #2 BFS

[LeetCode#664] Strange Printer 奇怪的打印机 There is a strange printer with the following two special requirements: The printer can only print a sequence of the same character each time. At each turn, the printer can print new characters starting from and ending at any places, and will cover the original existing characters. Given a string consists of lower English letters only, your job is to count the minimum number of turns the printer needed in order to print it. Example 1: Input: "aaabbb" Output: 2 Explanation: Print "aaa" first and then print "bbb". Example 2: Input: "aba" Output: 2 Explanation: Print "aaa" first and then print "b" from the second place of the string, which will cover the existing character 'a'. Hint: Length of the given string will not exceed 100.

一种奇怪的打印机每次只能打印一排相同的字符,然后可以在任意起点和终点位置之间打印新的字符,用来覆盖原有的字符。现在给了我们一个新的字符串,问我们需要几次可以正确的打印出来。 DP,不能用Greedy #1 DP 关心的是字符相等的地方,对于[i, j]范围的字符,我们从i+1位置上的字符开始遍历到j,如果和i位置上的字符相等,我们就以此位置为界,将[i+1, j]范围内的字符拆为两个部分,将二者的dp值加起来,和原dp值相比,取较小的那个。所以我们的递推式如下: dp[i][j] = min(dp[i][j], dp[i + 1][k - 1] + dp[k][j]) (s[k] == s[i] and i + 1 <= k <= j) 初始化: dp[i][i]=1,dp[i][j]= 1 + dp[i + 1][j] #2 递归+Memo [Mine] Same as Mine @ #546 Remove Boxes 在各个可能区间中搜索一个分割点,将区间分成两个子问题,使整个区间是最佳解。 [Mine]要发现:两个相同字符,中间可以是空串(打印0次)或其他字符串(递归调用),并不影响着两个字符可以用一次打印覆盖。连续相同字符不过是相同字符加空串,合并打印次数。

[LeetCode#661] Image Smoother 图片平滑器 Given a 2D integer matrix M representing the gray scale of an image, you need to design a smoother to make the gray scale of each cell becomes the average gray scale (rounding down) of all the 8 surrounding cells and itself. If a cell has less than 8 surrounding cells, then use as many as you can. Example 1: Input: [[1,1,1], [1,0,1], [1,1,1]] Output: [[0, 0, 0], [0, 0, 0], [0, 0, 0]] Explanation: For the point (0,0), (0,2), (2,0), (2,2): floor(3/4) = floor(0.75) = 0 For the point (0,1), (1,0), (1,2), (2,1): floor(5/6) = floor(0.83333333) = 0 For the point (1,1): floor(8/9) = floor(0.88888889) = 0 Note: The value in the given matrix is in the range of [0, 255]. The length and width of the given matrix are in the range of [1, 150].

一般来说都是用算子来跟图片进行卷积,但是由于这道题只是个Easy的题目,我们直接用土办法就能解了 直接对于每一个点统计其周围点的个数,然后累加像素值,做个除法就行了,注意边界情况的处理

[LeetCode#694] Number of Distinct Islands 不同岛屿的个数 Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water. Count the number of distinct islands. An island is considered to be the same as another if and only if one island can be translated (and not rotated or reflected) to equal the other. Example 1: 11000 11000 00011 00011 Given the above grid map, return 1. Example 2: 11011 10000 00001 11011 Given the above grid map, return 3. Notice that: 11 1 and 1 11 are considered different island shapes, because we do not consider reflection / rotation. Note: The length of each dimension in the given grid does not exceed 50.

不同"样子"的岛屿个数 两个相同的岛屿通过平移可以完全重合,但是不能旋转 通过相对位置坐标来判断,所有点均以左上角为原点来表示。 存入集合unordered_set中,利用其自动去重复的特性,就可以得到不同的岛屿的数量啦 #1 DFS 遍历点 #2 BFS 遍历点

[LeetCode#617] Merge Two Binary Trees 合并二叉树 Given two binary trees and imagine that when you put one of them to cover the other, some nodes of the two trees are overlapped while the others are not. You need to merge them into a new binary tree. The merge rule is that if two nodes overlap, then sum node values up as the new value of the merged node. Otherwise, the NOT null node will be used as the node of new tree. Example 1: Input: Tree 1 Tree 2 1 2 / \ / \ 3 2 1 3 / \ \ 5 4 7 Output: Merged tree: 3 / \ 4 5 / \ \ 5 4 7 Note: The merging process must start from the root nodes of both trees.

两个二叉树,让我们合并成一个,规则是,都存在的结点,就将结点值加起来,否则空的位置就由另一个树的结点来代替。 #1 同步递归两个树,只要至少有一个有节点,就继续递归,按要求取值 #2 不用每次创建新节点,如果只有一个树有节点,直接复用子树 TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) { if (!t1) return t2; if (!t2) return t1; TreeNode *t = new TreeNode(t1->val + t2->val); t->left = mergeTrees(t1->left, t2->left); t->right = mergeTrees(t1->right, t2->right); return t; }

[LeetCode#727] Minimum Window Subsequence 最小窗口序列 Given strings S and T, find the minimum (contiguous) substring W of S, so that T is a subsequence of W. If there is no such window in S that covers all characters in T, return the empty string "". If there are multiple such minimum-length windows, return the one with the left-most starting index. Example 1: Input: S = "abcdebdde", T = "bde" Output: "bcde" Explanation: "bcde" is the answer because it occurs before "bdde" which has the same length. "deb" is not a smaller window because the elements of T in the window must occur in order. Note: All the strings in the input will only contain lowercase letters. The length of S will be in the range [1, 20000]. The length of T will be in the range [1, 100].

两个字符串S和T,让我们找出S的一个长度最短子串W,使得T是W的子序列,如果长度相同,取起始位置靠前的。 暴力搜索的弊端:比如当 S = "bbbbdde", T = "bde"时,我们知道暴力搜索的双指针在S和T的第一个b匹配上之后,就开始检测S之后的字符能否包含T之后的所有字符,当匹配结束后,S的指针就会跳到第二个b开始匹配,由于有大量的重复b出现,所以每一个b都要遍历一遍,会达到平方级的复杂度 #1 dp[i][j] 表示范围S中前i个字符包含范围T中前j个字符的子串的起始位置,注意这里的包含是子序列包含关系。 dp[i][j] = (S[i - 1] == T[j - 1]) ? dp[i - 1][j - 1] : dp[i - 1][j]; #2 brute force + 双指针回朔优化 为避免以上暴力搜索的弊端,到从i=0匹配到最后后,回朔匹配回i=3,这样避免了前几个b的重复匹配

[LeetCode#712] Minimum ASCII Delete Sum for Two Strings 两个字符串的最小ASCII删除和 Given two strings s1, s2, find the lowest ASCII sum of deleted characters to make two strings equal. Example 1: Input: s1 = "sea", s2 = "eat" Output: 231 Explanation: Deleting "s" from "sea" adds the ASCII value of "s" (115) to the sum. Deleting "t" from "eat" adds 116 to the sum. At the end, both strings are equal, and 115 + 116 = 231 is the minimum sum possible to achieve this. Example 2: Input: s1 = "delete", s2 = "leet" Output: 403 Explanation: Deleting "dee" from "delete" to turn the string into "let", adds 100[d]+101[e]+101[e] to the sum. Deleting "e" from "leet" adds 101[e] to the sum. At the end, both strings are equal to "let", and the answer is 100+101+101+101 = 403. If instead we turned both strings into "lee" or "eet", we would get answers of 433 or 417, which are higher. Note: 0 < s1.length, s2.length <= 1000. All elements of each string will have an ASCII value in [97, 122].

两个字符串,让我们删除一些字符使得两个字符串相等,我们希望删除的字符的ASCII码最小。 #1 dp[i][j]表示字符串s1的前i个字符和字符串s2的前j个字符变相等所要删除的字符的最小ASCII码累加值。 初始化dp[0][j]和dp[i][0],累加数组 dp[i][j] = (s1[i - 1] == s2[j - 1]) ? dp[i - 1][j - 1] : min(dp[i - 1][j] + s1[i - 1], dp[i][j - 1] + s2[j - 1]); #2 空间优化为一维数组 #3 计算了字符串s1和s2的最大相同子序列的ASCII码值,然后用s1和s2的所有字符之和减去这个最大ASCII码值的两倍,就是要删除的字符的最小ASCII码值了。 dp[i][j]表示字符串s1的前i个字符和字符串s2点前j个字符中的最大相同子序列的ASCII值。 if (s1[i - 1] == s2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + s1[i - 1]; else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); [Mine]#3中用ASCII sum替代了相同子序列长度,这样不出错是因为 All elements of each string will have an ASCII value in [97, 122].

[LeetCode#718] Maximum Length of Repeated Subarray 最长的重复子数组 Given two integer arrays A and B, return the maximum length of an subarray that appears in both arrays. Example 1: Input: A: [1,2,3,2,1] B: [3,2,1,4,7] Output: 3 Explanation: The repeated subarray with maximum length is [3, 2, 1]. Note: 1 <= len(A), len(B) <= 1000 0 <= A[i], B[i] < 100

两个数组A和B,让我们返回连个数组的最长重复子数组 将数组换成字符串,实际这道题就是求Longest Common Substring的问题了(not Subsequence) dp[i][j]表示数组A的前i个数字和数组B的前j个数字的最长子数组的长度 dp[i][j] = (A[i - 1] == B[j - 1]) ? dp[i - 1][j - 1] + 1 : 0; res = max(res, dp[i][j]); --------------------------- If Longest Common Subsequence 无重复:dp[i][j]初始化应该赋值为其左边,上边,和左上边三个dp值中的最大值 有重复:要看其左边和上边的dp值是否相等,如果不相等,说明当前的相同字符已经匹配过了,所以不能再增加长度了,否则需要增加一个长度

[LeetCode#649] Dota2 Senate 刀塔二参议院 In the world of Dota2, there are two parties: the Radiant and the Dire. The Dota2 senate consists of senators coming from two parties. Now the senate wants to make a decision about a change in the Dota2 game. The voting for this change is a round-based procedure. In each round, each senator can exercise one of the two rights: Ban one senator's right: A senator can make another senator lose all his rights in this and all the following rounds. Announce the victory: If this senator found the senators who still have rights to vote are all from the same party, he can announce the victory and make the decision about the change in the game. Given a string representing each senator's party belonging. The character 'R' and 'D' represent the Radiant party and the Dire party respectively. Then if there are n senators, the size of the given string will be n. The round-based procedure starts from the first senator to the last senator in the given order. This procedure will last until the end of voting. All the senators who have lost their rights will be skipped during the procedure. Suppose every senator is smart enough and will play the best strategy for his own party, you need to predict which party will finally announce the victory and make the change in the Dota2 game. The output should be Radiant or Dire. Example 1: Input: "RD" Output: "Radiant" Explanation: The first senator comes from Radiant and he can just ban the next senator's right in the round 1. And the second senator can't exercise any rights any more since his right has been banned. And in the round 2, the first senator can just announce the victory since he is the only guy in the senate who can vote. Example 2: Input: "RDD" Output: "Dire" Explanation: The first senator comes from Radiant and he can just ban the next senator's right in the round 1. And the second senator can't exercise any rights anymore since his right has been banned. And the third senator comes from Dire and he can ban the first senator's right in the round 1. And in the round 2, the third senator can just announce the victory since he is the only guy in the senate who can vote. Note: The length of the given string will in the range [1, 10,000].

两个阵营按顺序Ban掉对方的英雄,看最后谁剩下来了,就返回哪个阵营。 #1 brute force 按照题意,先统计R和D的数量,然后一个个ban #2 Queue 用两个队列queue,把各自阵营的位置存入不同的队列里面 每次从两个队列各取一个位置出来,看其大小关系,小的那个说明在前面,就可以把后面的那个Ban掉,所以我们要把小的那个位置要加回队列里面,但是不能直接加原位置,因为下一轮才能再轮到他来Ban,所以我们要加上一个n,再排入队列。 样当某个队列为空时,推出循环

[LeetCode#717] 1-bit and 2-bit Characters 一位和两位字符 We have two special characters. The first character can be represented by one bit 0. The second character can be represented by two bits (10 or 11). Now given a string represented by several bits. Return whether the last character must be a one-bit character or not. The given string will always end with a zero. Example 1: Input: bits = [1, 0, 0] Output: True Explanation: The only way to decode it is two-bit character and one-bit character. So the last character is one-bit character. Example 2: Input: bits = [1, 1, 1, 0] Output: False Explanation: The only way to decode it is two-bit character and two-bit character. So the last character is NOT one-bit character. Note: 1 <= len(bits) <= 1000. bits[i] is always 0 or 1.

两种特殊的字符,一种是两位字符,只能是二进制的11和10,另一种是单个位字符,只能是二进制的0。现在给了我们一个只包含0和1的数组,问我们能否将其正确的分割,使得最后一个字符是个单个位字符。 #1 贪婪 因为两种字符互不干扰: 1 should be 11和10, 0 should be single 0 #2 简洁 while (i < n - 1) { i += bits[i] + 1; } return i == n - 1; #3 递归

[LeetCode#668] Kth Smallest Number in Multiplication Table 乘法表中的第K小的数字 Nearly every one have used the Multiplication Table. But could you find out the k-th smallest number quickly from the multiplication table? Given the height m and the length n of a m * n Multiplication Table, and a positive integer k, you need to return the k-th smallest number in this table. Example 1: Input: m = 3, n = 3, k = 5 Output: Explanation: The Multiplication Table: 1 2 3 2 4 6 3 6 9 The 5-th smallest number is 3 (1, 2, 2, 3, 3). Example 2: Input: m = 2, n = 3, k = 6 Output: Explanation: The Multiplication Table: 1 2 3 2 4 6 The 6-th smallest number is 6 (1, 2, 2, 3, 4, 6). Note: The m and n will be in the range [1, 30000]. The k will be in the range [1, m * n]

乘法表也是各行各列分别有序的 #1 二分搜索法,逐行算mid:利用乘法表,直接定位出位置 #2 算mid的另一个方法:从左下角的数字开始统计,如果该数字小于mid,说明该数字及上方所有数字都小于mid,cnt加上i个,然后向右移动一位继续比较。如果当前数字小于mid了,那么向上移动一位,直到横纵方向有一个越界停止 #3 对解法二的优化,再快一点,使用除法来快速定位新的j值 相似:#378 Kth Smallest Element in a Sorted Matrix

[LeetCode#699] Falling Squares 下落的方块 On an infinite number line (x-axis), we drop given squares in the order they are given. The i-th square dropped (positions[i] = (left, side_length)) is a square with the left-most point being positions[i][0] and sidelength positions[i][1]. The square is dropped with the bottom edge parallel to the number line, and from a higher height than all currently landed squares. We wait for each square to stick before dropping the next. The squares are infinitely sticky on their bottom edge, and will remain fixed to any positive length surface they touch (either the number line or another square). Squares dropped adjacent to each other will not stick together prematurely. Return a list ans of heights. Each height ans[i] represents the current highest height of any square we have dropped, after dropping squares represented by positions[0], positions[1], ..., positions[i]. Example 1: Input: [[1, 2], [2, 3], [6, 1]] Output: [2, 5, 5] Explanation: After the first drop of positions[0] = [1, 2]: _aa _aa ------- The maximum height of any square is 2. After the second drop of positions[1] = [2, 3]: __aaa __aaa __aaa _aa__ _aa__ -------------- The maximum height of any square is 5. The larger square stays on top of the smaller square despite where its center of gravity is, because squares are infinitely sticky on their bottom edge. After the third drop of positions[1] = [6, 1]: __aaa __aaa __aaa _aa _aa___a -------------- The maximum height of any square is still 5. Thus, we return an answer of [2, 5, 5]. Example 2: Input: [[100, 100], [200, 100]] Output: [100, 100] Explanation: Adjacent squares don't get stuck prematurely - only their bottom edge can stick to surfaces. Note: 1 <= positions.length <= 1000. 1 <= positions[i][0] <= 10^8. 1 <= positions[i][1] <= 10^6.

像俄罗斯方块,只有方块下落。只要有一点点部分搭在其他方块上面,整个方块都会在上面,并不会掉下来,让我们求每落下一个方块后的最大高度。 检查方块重叠 #1 brute force 判读两个方块是否重叠的方法是如果方块2的左边界小于方块1的右边界,并且方块2点右边界大于方块1点左边界。 #2 O(nlogn),二分法定位重叠区间。记录各个区间及其高度。 新落下方块,拆分区间,重新计算新区间高度 [Mine]假设各个方块不同颜色,从上向下看,能看到的颜色区间变化

[LeetCode#726] Number of Atoms 原子的个数 Given a chemical formula (given as a string), return the count of each atom. An atomic element always starts with an uppercase character, then zero or more lowercase letters, representing the name. 1 or more digits representing the count of that element may follow if the count is greater than 1. If the count is 1, no digits will follow. For example, H2O and H2O2 are possible, but H1O2 is impossible. Two formulas concatenated together produce another formula. For example, H2O2He3Mg4 is also a formula. A formula placed in parentheses, and a count (optionally added) is also a formula. For example, (H2O2) and (H2O2)3 are formulas. Given a formula, output the count of all elements as a string in the following form: the first name (in sorted order), followed by its count (if that count is more than 1), followed by the second name (in sorted order), followed by its count (if that count is more than 1), and so on. Example 1: Input: formula = "H2O" Output: "H2O" Explanation: The count of elements are {'H': 2, 'O': 1}. Example 2: Input: formula = "Mg(OH)2" Output: "H2MgO2" Explanation: The count of elements are {'H': 2, 'Mg': 1, 'O': 2}. Example 3: Input: formula = "K4(ON(SO3)2)2" Output: "K4N2O14S4" Explanation: The count of elements are {'K': 4, 'N': 2, 'O': 14, 'S': 4}. Note: All atom names consist of lowercase letters, except for the first character which is uppercase. The length of formula will be in the range [1, 1000]. formula will only consist of letters, digits, and round parentheses, and is a valid formula as defined in the problem.

元素是按字母顺序排列的,统计括号里的原子个数,然后如果括号外面有数字,那么括号里每个原子的个数乘以外面的数字即可 #1 递归 建立了每个元素和其出现次数的映射,就可以生成返回的字符串了,由于需要按元素的字母顺序排列,所以我们使用TreeMap来建立映射。 #2 栈 + 迭代

[LeetCode#693] Binary Number with Alternating Bits 有交替位的二进制数 Given a positive integer, check whether it has alternating bits: namely, if two adjacent bits will always have different values. Example 1: Input: 5 Output: True Explanation: The binary representation of 5 is: 101 Example 2: Input: 7 Output: False Explanation: The binary representation of 7 is: 111. Example 3: Input: 11 Output: False Explanation: The binary representation of 11 is: 1011. Example 4: Input: 10 Output: True Explanation: The binary representation of 10 is: 1010.

判断一个二进制数的1和0是否是交替出现的 #1 逐位判断 #2 target 0/1切换(d ^= 1),平移检测最低位。 #3 错位相加,从而组成全1的二进制数。 然后(n+1)&n == 0来判断是否全1 #4 将n右移两位,再和原来的n亦或,得到的新n其实就是除了最高位,其余都是0的数。 然后n&(n-1) == 0 来判断是否只有一个1

[LeetCode#689] Maximum Sum of 3 Non-Overlapping Subarrays 三个非重叠子数组的最大和 In a given array nums of positive integers, find three non-overlapping subarrays with maximum sum. Each subarray will be of size k, and we want to maximize the sum of all 3*k entries. Return the result as a list of indices representing the starting position of each interval (0-indexed). If there are multiple answers, return the lexicographically smallest one. Example: Input: [1,2,1,2,6,7,5,1], 2 Output: [0, 3, 5] Explanation: Subarrays [1, 2], [2, 6], [7, 5] correspond to the starting indices [0, 3, 5]. We could have also taken [2, 1], but an answer of [1, 3, 5] would be lexicographically larger. Note: nums.length will be between 1 and 20000. nums[i] will be between 1 and 65535. k will be between 1 and floor(nums.length / 3).

只包含正数的数组,让我们找三个长度为k的不重叠的子数组,使得所有子数组的数字之和最大。 累加和数组 中间子数组的起点不能是从开头到结尾整个区间,必须要在首尾各留出k个位置给其他两个数组。中间子数组:累加和 在左右两边的区间内分别找出和最大的子数组:DP left[i]表示在区间[0, i]范围内长度为k且和最大的子数组的起始位置 right[i]表示在区间[i, n - 1]范围内长度为k且和最大的子数组的起始位置 left[i]和right[i]都好求,之后遍历中间可能的中间数组起始点,利用累加和计算各个数组的sum,找到三个sum最大。

[LeetCode#652] Find Duplicate Subtrees 寻找重复树 Given a binary tree, return all duplicate subtrees. For each kind of duplicate subtrees, you only need to return the root node of any oneof them. Two trees are duplicate if they have the same structure with same node values. Example 1: 1 / \ 2 3 / / \ 4 2 4 / 4 The following are two duplicate subtrees: 2 / 4 and 4 Therefore, you need to return above trees' root in the form of a list.

后序遍历,还有数组序列化,并且建立序列化跟其出现次数的映射,(子树序列化) 这样如果我们得到某个结点的序列化字符串,而该字符串之前正好出现的次数为1,说明之前已经有一个重复树了,我们将当前结点存入结果res,这样保证了多个重复树只会存入一个结点 递归+子树序列化+字符串出现次数映射

[LeetCode#651] 4 Keys Keyboard 四键的键盘 Imagine you have a special keyboard with the following keys: Key 1: (A): Print one 'A' on screen. Key 2: (Ctrl-A): Select the whole screen. Key 3: (Ctrl-C): Copy selection to buffer. Key 4: (Ctrl-V): Print buffer on screen appending it after what has already been printed. Now, you can only press the keyboard for N times (with the above four keys), find out the maximum numbers of 'A' you can print on screen. Example 1: Input: N = 3 Output: 3 Explanation: We can at most get 3 A's on screen by pressing following key sequence: A, A, A Example 2: Input: N = 7 Output: 9 Explanation: We can at most get 9 A's on screen by pressing following key sequence: A, A, A, Ctrl A, Ctrl C, Ctrl V, Ctrl V Note: 1 <= N <= 50 Answers will be in the range of 32-bit signed integer.

四个操作,分别是打印A,全选,复制,粘贴。每个操作都算一个步骤,给了我们一个数字N,问我们N个操作最多能输出多个A。 N步最少都能打印N个A出来,因为我们可以每步都是打印A。 由于全选和复制要占用两步,所以能增加A的个数的操作其实只有N-2步,那么我们如何确定打印几个A,剩下都是粘贴呢 打印A的次数在[1, N-3]之间,粘贴的次数为N-2-i,加上打印出的部分,就是N-1-i了 #1 递归 int maxA(int N) { int res = N; for (int i = 1; i < N - 2; ++i) { res = max(res, maxA(i) * (N - 1 - i)); } return res; } #2 DP [Mine]所以,最终答案不一定只有一次Ctrl A, Ctrl C #3 O(1) ????

[LeetCode#672] Bulb Switcher II 灯泡开关之二 There is a room with n lights which are turned on initially and 4 buttons on the wall. After performing exactly m unknown operations towards buttons, you need to return how many different kinds of status of the n lights could be. Suppose n lights are labeled as number [1, 2, 3 ..., n], function of these 4 buttons are given below: Flip all the lights. Flip lights with even numbers. Flip lights with odd numbers. Flip lights with (3k + 1) numbers, k = 0, 1, 2, ... Example 1: Input: n = 1, m = 1. Output: 2 Explanation: Status can be: [on], [off] Example 2: Input: n = 2, m = 1. Output: 3 Explanation: Status can be: [on, off], [off, on], [off, off] Example 3: Input: n = 3, m = 1. Output: 4 Explanation: Status can be: [off, on, off], [on, off, on], [off, off, off], [off, on, on]. Note: n and m both fit in range [0, 1000].

四种关灯方法,全关,关偶数灯,关奇数灯,关3k+1的灯。现在给我们n盏灯,允许m步操作,问我们总共能组成多少种不同的状态。 思路:返回总个数。觉得应该不能用递归的暴力破解来做,一般都是用DP来做啊 如果结果是一个超大数,一般都会对一个超大数10e7来取余,而这道题并没有,所以是一个很大的hint 实际上,由于不是超大数,所以不用DP,直接找规律。 由于,关偶数,关奇数和关3k+1,实际造成了6个一组的重复。 #1 BFS #2 这道题最多只有8中情况,所以很适合分情况来讨论: - 当m和n其中有任意一个数是0时,返回1 - 当n = 1时 只有两种情况,0和1 - 当n = 2时, 这时候要看m的次数,如果m = 1,那么有三种状态 00,01,10 当m > 1时,那么有四种状态,00,01,10,11 - 当m = 1时, 此时n至少为3,那么我们有四种状态,000,010,101,011 - 当m = 2时, 此时n至少为3,我们有七种状态:111,101,010,100,000,001,110 - 当m > 2时, 此时n至少为3,我们有八种状态:111,101,010,100,000,001,110,011 如果有4盏灯,也只能有8种情况

[LeetCode#631] Design Excel Sum Formula 设计Excel表格求和公式 Your task is to design the basic function of Excel and implement the function of sum formula. Specifically, you need to implement the following functions: Excel(int H, char W): This is the constructor. The inputs represents the height and width of the Excel form. His a positive integer, range from 1 to 26. It represents the height. W is a character range from 'A' to 'Z'. It represents that the width is the number of characters from 'A' to W. The Excel form content is represented by a height * width 2D integer array C, it should be initialized to zero. You should assume that the first row of C starts from 1, and the first column of C starts from 'A'. void Set(int row, char column, int val): Change the value at C(row, column) to be val. int Get(int row, char column): Return the value at C(row, column). int Sum(int row, char column, List of Strings : numbers): This function calculate and set the value at C(row, column), where the value should be the sum of cells represented by numbers. This function return the sum result at C(row, column). This sum formula should exist until this cell is overlapped by another value or another sum formula. numbers is a list of strings that each string represent a cell or a range of cells. If the string represent a single cell, then it has the following format : ColRow. For example, "F7" represents the cell at (7, F). If the string represent a range of cells, then it has the following format : ColRow1:ColRow2. The range will always be a rectangle, and ColRow1 represent the position of the top-left cell, and ColRow2 represents the position of the bottom-right cell. Example 1: Excel(3,"C"); // construct a 3*3 2D array with all zero. // A B C // 1 0 0 0 // 2 0 0 0 // 3 0 0 0 Set(1, "A", 2); // set C(1,"A") to be 2. // A B C // 1 2 0 0 // 2 0 0 0 // 3 0 0 0 Sum(3, "C", ["A1", "A1:B2"]); // set C(3,"C") to be the sum of value at C(1,"A") and the values sum of the rectangle range whose top-left cell is C(1,"A") and bottom-right cell is C(2,"B"). Return 4. // A B C // 1 2 0 0 // 2 0 0 0 // 3 0 0 4 Set(2, "B", 2); // set C(2,"B") to be 2. Note C(3, "C") should also be changed. // A B C // 1 2 0 0 // 2 0 2 0 // 3 0 0 6 Note: You could assume that there won't be any circular sum reference. For example, A1 = sum(B1) and B1 = sum(A1). The test cases are using double-quotes to represent a character. Please remember to RESET your class variables declared in class Excel, as static/class variables are persisted across multiple test cases. Please see here for more details.

在Excel中,相当于已经把A1和A2关联起来了,只要A2点值发生了改变,A1的值也会跟着变 需要一个二维数组mat来保存数据,然后需要一个map来建立单元格和区域和之间的映射 [Mine]Set是设置值到单元格,Sum是设置区域公式到单元格。 Get和Sum时都要依据公式计算区域和,由于区域中可能还有其他公式,所以需要递归调用Get->Sum

[LeetCode#609] Find Duplicate File in System 在系统中寻找重复文件 Given a list of directory info including directory path, and all the files with contents in this directory, you need to find out all the groups of duplicate files in the file system in terms of their paths. A group of duplicate files consists of at least two files that have exactly the same content. A single directory info string in the input list has the following format: "root/d1/d2/.../dm f1.txt(f1_content) f2.txt(f2_content) ... fn.txt(fn_content)" It means there are n files (f1.txt, f2.txt ... fn.txt with content f1_content, f2_content ... fn_content, respectively) in directory root/d1/d2/.../dm. Note that n >= 1 and m >= 0. If m = 0, it means the directory is just the root directory. The output is a list of group of duplicate file paths. For each group, it contains all the file paths of the files that have the same content. A file path is a string that has the following format: "directory_path/file_name.txt" Example 1: Input: ["root/a 1.txt(abcd) 2.txt(efgh)", "root/c 3.txt(abcd)", "root/c/d 4.txt(efgh)", "root 4.txt(efgh)"] Output: [["root/a/2.txt","root/c/d/4.txt","root/4.txt"],["root/a/1.txt","root/c/3.txt"]] Note: No order is required for the final output. You may assume the directory name, file name and file content only has letters and digits, and the length of file content is in the range of [1,50]. The number of files given is in the range of [1,20000]. You may assume no files or directories share the same name in the same directory. You may assume each given directory info represents a unique directory. Directory path and file info are separated by a single blank space. Follow-up beyond contest: Imagine you are given a real file system, how will you search files? DFS or BFS? If the file content is very large (GB level), how will you modify your solution? If you can only read the file by 1kb each time, how will you modify your solution? What is the time complexity of your modified solution? What is the most time-consuming part and memory consuming part of it? How to optimize? How to make sure the duplicated files you find are not false positive?

堆字符串数组,每个字符串中包含了文件路径,文件名称和内容,让我们找到重复的文件,这里只要文件内容相同即可,不用管文件名是否相同,而且返回结果中要带上文件的路径。 处理字符串,把路径,文件名,和文件内容从一个字符串中拆出来 Hashmap, 建立一个文件内容和文件路径加文件名组成的数组的映射

[LeetCode#646] Maximum Length of Pair Chain 链对的最大长度 You are given n pairs of numbers. In every pair, the first number is always smaller than the second number. Now, we define a pair (c, d) can follow another pair (a, b) if and only if b < c. Chain of pairs can be formed in this fashion. Given a set of pairs, find the length longest chain which can be formed. You needn't use up all the given pairs. You can select pairs in any order. Example 1: Input: [[1,2], [2,3], [3,4]] Output: 2 Explanation: The longest chain is [1,2] -> [3,4] Note: The number of given pairs will be in the range [1, 1000].

如果后面链对的首元素大于前链对的末元素,那么这两个链对就可以链起来,问我们最大能链多少个。 按链对的尾元素进行排序,小的放前面。这样我们就可以利用Greedy算法进行求解了。 用一个栈,先将第一个链对压入栈,然后对于后面遍历到的每一个链对,我们看其首元素是否大于栈顶链对的尾元素,如果大于的话,就将当前链对压入栈,这样最后我们返回栈中元素的个数即可 "用dp 就和LIS一样了" similar to"435. Non-overlapping Intervals"

[LeetCode#606] Construct String from Binary Tree 根据二叉树创建字符串 You need to construct a string consists of parenthesis and integers from a binary tree with the preorder traversing way. The null node needs to be represented by empty parenthesis pair "()". And you need to omit all the empty parenthesis pairs that don't affect the one-to-one mapping relationship between the string and the original binary tree. Example 1: Input: Binary tree: [1,2,3,4] 1 / \ 2 3 / 4 Output: "1(2(4))(3)" Explanation: Originallay it needs to be "1(2(4)())(3()())", but you need to omit all the unnecessary empty parenthesis pairs. And it will be "1(2(4))(3)". Example 2: Input: Binary tree: [1,2,3,null,4] 1 / \ 2 3 \ 4 Output: "1(2()(4))(3)" Explanation: Almost the same as the first example, except we can't omit the first parenthesis pair to break the one-to-one mapping relationship between the input and the output.

如果左子结点为空,右子结点不为空时,需要在父结点后加上个空括号,而右子结点如果不存在,或者左右子结点都不存在就不需要这么做。 #1 先序遍历,从左到右生成字符串 #2后序遍历,生成左右子树字符串,加括号和父节点组成新字符串。

[LeetCode#621] Task Scheduler 任务行程表 Given a char array representing tasks CPU need to do. It contains capital letters A to Z where different letters represent different tasks.Tasks could be done without original order. Each task could be done in one interval. For each interval, CPU could finish one task or just be idle. However, there is a non-negative cooling interval n that means between two same tasks, there must be at least n intervals that CPU are doing different tasks or just be idle. You need to return the least number of intervals the CPU will take to finish all the given tasks. Example 1: Input: tasks = ['A','A','A','B','B','B'], n = 2 Output: 8 Explanation: A -> B -> idle -> A -> B -> idle -> A -> B. Note: The number of tasks is in the range [1, 10000]. The integer n is in the range [0, 100].

安排CPU的任务,规定在两个相同任务之间至少隔n个时间点。 #1 首先应该处理的出现次数最多的那个任务,先确定好这些高频任务,然后再来安排那些低频任务。如果任务F的出现频率最高,为k次,那么我们用n个空位将每两个F分隔开,然后我们按顺序加入其他低频的任务 (任务最大次数 - 1) * (n + 1) + 字母个数为出现次数最多的任务个数 [Mine]填空题,有统计后直接算结果的, 也有统计后,一段段填的 注意字母个数为出现次数最多的任务可能不止一个

[LeetCode#677] Map Sum Pairs 映射配对之和 Implement a MapSum class with insert, and sum methods. For the method insert, you'll be given a pair of (string, integer). The string represents the key and the integer represents the value. If the key already existed, then the original key-value pair will be overridden to the new one. For the method sum, you'll be given a string representing the prefix, and you need to return the sum of all the pairs' value whose key starts with the prefix. Example 1: Input: insert("apple", 3), Output: Null Input: sum("ap"), Output: 3 Input: insert("app", 2), Output: Null Input: sum("ap"), Output: 5

实现一个MapSum类,里面有两个方法,insert和sum,其中insert就是插入一个键值对,而sum方法比较特别,是在找一个前缀,需要将所有有此前缀的单词的值累加起来返回。 #1 map: 建立前缀和一个pair之间的映射,这里的pair的第一个值表示该词的值,第二个值表示将该词作为前缀的所有词的累加值 sum,直接将pair中的两个值相加即可 insert: 将first值更新为val,然后就是遍历其所有的前缀了,给每个前缀的second都加上diff即可 #2 带排序的map,insert就是把单词加入map。在map里会按照字母顺序自动排序,然后在sum函数里,我们根据prefix来用二分查找快速定位到第一个不小于prefix的位置,然后向后遍历,向后遍历的都是以prefix为前缀的单词,如果我们发现某个单词不是以prefix为前缀了,直接break;否则就累加其val值

[LeetCode#715] Range Module 范围模块 A Range Module is a module that tracks ranges of numbers. Your task is to design and implement the following interfaces in an efficient manner. addRange(int left, int right) Adds the half-open interval [left, right), tracking every real number in that interval. Adding an interval that partially overlaps with currently tracked numbers should add any numbers in the interval [left, right) that are not already tracked. queryRange(int left, int right) Returns true if and only if every real number in the interval [left, right) is currently being tracked. removeRange(int left, int right) Stops tracking every real number currently being tracked in the interval [left, right). Example 1: addRange(10, 20): null removeRange(14, 16): null queryRange(10, 14): true (Every number in [10, 14) is being tracked) queryRange(13, 15): false (Numbers like 14, 14.03, 14.17 in [13, 15) are not being tracked) queryRange(16, 17): true (The number 16 in [16, 17) is still being tracked, despite the remove operation) Note: A half open interval [left, right) denotes all real numbers left <= x < right. 0 < left < right < 10^9 in all calls to addRange, queryRange, removeRange. The total number of calls to addRange in a single test case is at most 1000. The total number of calls to queryRange in a single test case is at most 5000. The total number of calls to removeRange in a single test case is at most 1000.

实现一个RangeModule的类,里面有三个功能函数,分别好似插入范围,查找范围,删除范围 对于查找范围函数,由于题目中说只要有数字未被包括,就返回false。那么我们反过来想,只有当某个范围完全覆盖了这个要查找的范围才会返回true TreeMap来建立范围的起始位置和结束位置之间的映射,利用了TreeMap的自动排序功能,其会根据起始位置从小到大进行排序。既然是有序的,我们就可以利用二分法来快速进行查找了。

[LeetCode#716] Max Stack 最大栈 Design a max stack that supports push, pop, top, peekMax and popMax. push(x) -- Push element x onto stack. pop() -- Remove the element on top of the stack and return it. top() -- Get the element on the top. peekMax() -- Retrieve the maximum element in the stack. popMax() -- Retrieve the maximum element in the stack, and remove it. If you find more than one maximum elements, only remove the top-most one. Example 1: MaxStack stack = new MaxStack(); stack.push(5); stack.push(1); stack.push(5); stack.top(); -> 5 stack.popMax(); -> 5 stack.top(); -> 1 stack.peekMax(); -> 5 stack.pop(); -> 1 stack.top(); -> 5 Note: -1e7 <= x <= 1e7 Number of operations won't exceed 10000. The last four operations won't be called when stack is empty.

实现一个最大栈,包含一般栈的功能,但是还新加了两个功能peekMax()和popMax() #1 双栈:s2保存的是目前为止最大的数字,s1保存所有的数字 #2 用一个list链表来保存所有的数字,然后建立一个数字和包含所有相同的数字的位置iterator的向量容器的映射map。

[LeetCode#637] Average of Levels in Binary Tree 二叉树的层平均值 Given a non-empty binary tree, return the average value of the nodes on each level in the form of an array. Example 1: Input: 3 / \ 9 20 / \ 15 7 Output: [3, 14.5, 11] Explanation: The average value of nodes on level 0 is 3, on level 1 is 14.5, and on level 2 is 11. Hence return [3, 14.5, 11]. Note: The range of node's value is in the range of 32-bit signed integer.

层级遍历 先序遍历

[LeetCode#636] Exclusive Time of Functions 函数的独家时间 Given the running logs of n functions that are executed in a nonpreemptive single threaded CPU, find the exclusive time of these functions. Each function has a unique id, start from 0 to n-1. A function may be called recursively or by another function. A log is a string has this format : function_id:start_or_end:timestamp. For example, "0:start:0" means function 0 starts from the very beginning of time 0. "0:end:0" means function 0 ends to the very end of time 0. Exclusive time of a function is defined as the time spent within this function, the time spent by calling other functions should not be considered as this function's exclusive time. You should return the exclusive time of each function sorted by their function id. Example 1: Input: n = 2 logs = ["0:start:0", "1:start:2", "1:end:5", "0:end:6"] Output:[3, 4] Explanation: Function 0 starts at time 0, then it executes 2 units of time and reaches the end of time 1. Now function 0 calls function 1, function 1 starts at time 2, executes 4 units of time and end at time 5. Function 0 is running again at time 6, and also end at the time 6, thus executes 1 unit of time. So function 0 totally execute 2 + 1 = 3 units of time, and function 1 totally execute 4 units of time. Note: Input logs will be sorted by timestamp, NOT log id. Your output should be sorted by function id, which means the 0th element of your output corresponds to the exclusive time of function 0. Two functions won't start or end at the same time. Functions could be called recursively, and will always end. 1 <= n <= 100

当一个函数start了之后,并不需要必须有end,可以直接被另一个程序start的时候强行关闭。而且,在某个时间点上调用end时,也不需要前面非得调用start,可以直接在某个时间点来个end,这样也算执行了1秒,得+1秒 ["0:start:0","0:start:2","0:end:5","1:start:7","1:end:7","0:end:8"] Expected: [8,1] 当函数0在时间点2时再次开启时,前面那个函数0应该没有被强制关闭,所以现在实际上有两个函数0在执行,所以当我们在时间点5关掉一个函数0时,还有另一个函数0在跑,所以时间点6还是函数0的,还得给函数0续1秒。 用栈

[LeetCode#663] Equal Tree Partition 划分等价树 Given a binary tree with n nodes, your task is to check if it's possible to partition the tree to two trees which have the equal sum of values after removing exactly one edge on the original tree. Example 1: Input: 5 / \ 10 10 / \ 2 3 Output: True Explanation: 5 / 10 Sum: 15 10 / \ 2 3 Sum: 15 Example 2: Input: 1 / \ 2 10 / \ 2 20 Output: False Explanation: You can't split the tree into two trees with equal sum after removing exactly one edge on the tree.

当移除一条边后,被分成的两棵树的结点之和需要相等。[Mine]注意value可以是负数,所以sum可以是0 如果我们将每个结点的结点值变成其所有子结点的结点值之和再加上当前的结点值.那么我们就可以发现其实只要断开位置的结点值是根结点值的一半,就存在等价划分。 递归更新sum。 unordered_map:建立更新后的结点值和其出现次数之间的映射,这样只有map中0的个数大于1的时候,才返回true if (rootSum == 0) return m[0] > 1; return rootSum % 2 == 0 && m.count(rootSum / 2);

[LeetCode#728] Self Dividing Numbers 自整除数字 A self-dividing number is a number that is divisible by every digit it contains. For example, 128 is a self-dividing number because 128 % 1 == 0, 128 % 2 == 0, and 128 % 8 == 0. Also, a self-dividing number is not allowed to contain the digit zero. Given a lower and upper number bound, output a list of every possible self dividing number, including the bounds if possible. Example 1: Input: left = 1, right = 22 Output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22] Note: The boundaries of each input argument are 1 <= left <= right <= 10000.

找一个给定范围内的所有的自整除数字,所谓的自整除数字就是该数字可以整除其每一个位上的数字。 brute force

[LeetCode#644] Maximum Average Subarray II 子数组的最大平均值之二 Given an array consisting of n integers, find the contiguous subarray whose length is greater than or equal to k that has the maximum average value. And you need to output the maximum average value. Example 1: Input: [1,12,-5,-6,50,3], k = 4 Output: 12.75 Explanation: when length is 5, maximum average value is 10.8, when length is 6, maximum average value is 9.16667. Thus return 12.75. Note: 1 <= k <= n <= 10,000. Elements of the given array will be in range [-10,000, 10,000]. The answer with the calculation error less than 10^-5 will be accepted.

找长度大于等于k的子数组的最大平均值 #1 brute force 利用累加和数组,遍历所有的长度大于等于k的子数组,并计算平均值并更新结果res。 Note: 更新结果res的步骤不能写成res = min(res, t / (i + 1)) 这种形式,会TLE,必须要在if中判断 t > res * (i + 1) 才能accept,写成t / (i + 1) > res 也不行,必须要用乘法 #2 空间优化 不用累加和数组,使用了preSum和sum两个变量来代替 #3 O(Nlog(max - min)),其中max和min分别是数组中的最大值和最小值(也可空间优化为不用差值累加数组,只用两个变量,像#2) 套路: 1. 只要满足一定误差,所以用二分,直接二分最后的平均值 2. 在判断某个平均值是否满足时,转换为求连续子数组的差值累加和大于0,并且一样,可以用差值累加数组,快速判断每个区间段的差值累加值,及是否有长度大于k且差值累加和大于0的区间 首先找出数组中的最小值left和最大值right,因为这将构成最大平均值的区间。然后每次找到left和right的平均值mid,对于mid,在数组内找是否存在一个长度大于等于k的连续区间,其平均值大于mid,如果存在,那么说明mid还不是最大平均值,所以修改左边界left;否则说明mid已经大于等于左右长度大于等于k的所有连续区间的最大平均值了,所以此时修改右边界right。这样当left和right逐渐收敛到一点的时候,该收敛点就是最大平均值。 Rule: 如果我们已经算出来了这个最大平均值maxAvg,那么对于任意一个长度大于等于k的数组,如果让每个数字都减去maxAvg,那么得到的累加差值一定是小于等于0的 [Mine]二分搜索的不是区间的起始,结束位置,目标是符合条件的最大平均值。left/right并不是区间范围,也不是区间内最大最小数(虽然初始化是),他们是逼近符合条件最大平均值的上下沿 差值累加数组,可以计算对当前mid,长度大于k区间[j,i]的差值累加值,如果差值累加值大于0,依据rule,mid就不是最大平均值 [Mine]传说有O(n)解法,是基于单调队列的。没有找到code,但这里能看到一些端倪: mid=min+(max-min)/2,看区间差值累加和的分布,也许,我们要找差值累加和最大的一段大于等于k的区间

[LeetCode#639] Decode Ways II 解码方法之二 A message containing letters from A-Z is being encoded to numbers using the following mapping way: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 Beyond that, now the encoded string can also contain the character '*', which can be treated as one of the numbers from 1 to 9. Given the encoded message containing digits and the character '*', return the total number of ways to decode it. Also, since the answer may be very large, you should return the output mod 109 + 7. Example 1: Input: "*" Output: 9 Explanation: The encoded message can be decoded to the string: "A", "B", "C", "D", "E", "F", "G", "H", "I". Example 2: Input: "1*" Output: 9 + 9 = 18 Note: The length of the input string will fit in range [1, 105]. The input string will only contain the character '*' and digits '0' - '9'.

数字解码为字母,引入星号,代表任意一个数字。 #1 DP dp[i]表示前i个字符的解码方法等个数,长度为字符串的长度加1。 初始化: 如果字符串第一个字符是0,那么直接返回0,如果是*,则dp[1]初始化为9,否则初始化为1。 当前遍历到的字符s[i-1],只有三种情况: s[i-1]是0: 前面的数字只能是1或2,其他的直接返回0即可。那么当前面的数字是1或2的时候,dp[i]的种类数就跟dp[i-2]相等;如果前面的数是星号的时候,那么前面的数可以为1或者2,这样就相等于两倍的dp[i-2]; s[i-1]为1到9之间的数字: 当前数字是可以单独拆分出来的,那么dp[i]至少是等于dp[i-1]的;当前数字可以跟前面的数字组成一个小于等于26的两位数的话,dp[i]还需要加上dp[i-2];如果前面的数字为星号的话,那么要看当前的数字是否小于等于6,如果是小于等于6,那么前面的数字就可以是1或者2了,此时dp[i]需要加上两倍的dp[i-2],如果大于6,那么前面的数字只能是1,所以dp[i]只能加上dp[i-2]。 s[i-1]为星号:创造9种可以单独拆分的方法,所以那么dp[i]至少是等于9倍的dp[i-1];如果前面的数字是1,那么当前的9种情况都可以跟前面的数字组成两位数,所以dp[i]需要加上9倍的dp[i-2];如果前面的数字是2,那么只有小于等于6的6种情况都可以跟前面的数字组成两位数,所以dp[i]需要加上6倍的dp[i-2];如果前面的数字是星号,那么就是上面两种情况的总和,dp[i]需要加上15倍的dp[i-2]。 #2 空间压缩的DP e0表示当前可以获得的解码的次数,当前数字可以为任意数 (也就是上面解法中的dp[i]) e1表示当前可以获得的解码的次数,当前数字为1 e2表示当前可以获得的解码的次数,当前数字为2 f0, f1, f2分别为处理完当前字符c的e0, e1, e2的值 e0就相当于dp[i-1],e1和e2相当于两种不同情况的dp[i-2]

[LeetCode#697] Degree of an Array 数组的度 Given a non-empty array of non-negative integers nums, the degree of this array is defined as the maximum frequency of any one of its elements. Your task is to find the smallest possible length of a (contiguous) subarray of nums, that has the same degree as nums. Example 1: Input: [1, 2, 2, 3, 1] Output: 2 Explanation: The input array has a degree of 2 because both elements 1 and 2 appear twice. Of the subarrays that have the same degree: [1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2] The shortest length is 2. So return 2. Example 2: Input: [1,2,2,3,1,4,2] Output: 6 Note: nums.length will be between 1 and 50,000. nums[i] will be an integer between 0 and 49,999.

数组的度为某个或某些数字出现最多的次数,要我们找最短的子数组使其和原数组拥有相同的度。 #1 哈希表来建立每个数字和其出现次数之间的映射。哈希表来建立每个数字和其出现次数之间的映射。 #1 只用了一次遍历,建立数字出现次数的哈希表,还有就是建立每个数字和其第一次出现位置之间的映射,那么我们当前遍历的位置其实可以看作是尾位置,还是可以计算子数组的长度的。

[LeetCode#665] Non-decreasing Array 非递减数列 Given an array with n integers, your task is to check if it could become non-decreasing by modifying at most 1element. We define an array is non-decreasing if array[i] <= array[i + 1] holds for every i (1 <= i < n). Example 1: Input: [4,2,3] Output: True Explanation: You could modify the first 4 to 1 to get a non-decreasing array. Example 2: Input: [4,2,1] Output: False Explanation: You can't get a non-decreasing array by modify at most one element. Note: The n belongs to [1, 10,000].

最多有1次修改某个数字的机会,问能不能将数组变为非递减数组。 当我们发现后面的数字小于前面的数字产生冲突后,有时候需要修改前面较大的数字(之前峰值变小,成为非递减),有时候却要修改后面较小的那个数字(提升低值,成为非递减) [Mine] i-1,i,i+1 ; if a[i+1] < a[i],发现递减,要看a[i-1] and a[i+1] if a[i-1] <= a[i+1], change a[i]; if a[i-1] > a[i+1], change a[i+1]

[LeetCode#676] Implement Magic Dictionary 实现神奇字典 Implement a magic directory with buildDict, and search methods. For the method buildDict, you'll be given a list of non-repetitive words to build a dictionary. For the method search, you'll be given a word, and judge whether if you modify exactly one character into another character in this word, the modified word is in the dictionary you just built. Example 1: Input: buildDict(["hello", "leetcode"]), Output: Null Input: search("hello"), Output: False Input: search("hhllo"), Output: True Input: search("hell"), Output: False Input: search("leetcoded"), Output: False Note: You may assume that all the inputs are consist of lowercase letters a-z. For contest purpose, the test data is rather small by now. You could think about highly efficient algorithm after the contest. Please remember to RESET your class variables declared in class MagicDictionary, as static/class variables are persisted across multiple test cases. Please see here for more details.

有一些单词,实现的功能是当我们搜索一个单词,只有存在和这个单词只有一个位置上的字符不相同的才能返回true,否则就返回false,注意完全相同也是返回false,必须要有一个字符不同。 #1 数据结构就是根据单词的长度来分,把长度相同相同的单词放到一起,这样就可以减少搜索量。逐字符对比,计数 #2 所有的单词都放到一个集合中,然后在search函数中,我们遍历要搜索的单词的每个字符,然后把每个字符都用a-z中的字符替换一下,形成一个新词,当然遇到本身要跳过。然后在集合中看是否存在,存在的话就返回true。

[LeetCode#638] Shopping Offers 购物优惠 In LeetCode Store, there are some kinds of items to sell. Each item has a price. However, there are some special offers, and a special offer consists of one or more different kinds of items with a sale price. You are given the each item's price, a set of special offers, and the number we need to buy for each item. The job is to output the lowest price you have to pay for exactly certain items as given, where you could make optimal use of the special offers. Each special offer is represented in the form of an array, the last number represents the price you need to pay for this special offer, other numbers represents how many specific items you could get if you buy this offer. You could use any of special offers as many times as you want. Example 1: Input: [2,5], [[3,0,5],[1,2,10]], [3,2] Output: 14 Explanation: There are two kinds of items, A and B. Their prices are $2 and $5 respectively. In special offer 1, you can pay $5 for 3A and 0B In special offer 2, you can pay $10 for 1A and 2B. You need to buy 3A and 2B, so you may pay $10 for 1A and 2B (special offer #2), and $4 for 2A. Example 2: Input: [2,3,4], [[1,1,0,4],[2,2,1,9]], [1,2,1] Output: 11 Explanation: The price of A is $2, and $3 for B, $4 for C. You may pay $4 for 1A and 1B, and $9 for 2A ,2B and 1C. You need to buy 1A ,2B and 1C, so you may pay $4 for 1A and 1B (special offer #1), and $3 for 1B, $4 for 1C. You cannot add more items, though only $9 for 2A ,2B and 1C. Note: There are at most 6 kinds of items, 100 special offers. For each item, you need to buy at most 6 of them. You are not allowed to buy more items than you want, even if that would lower the overall price.

有一些商品,各自有不同的价格,然后给我们了一些优惠券,可以在优惠的价格买各种商品若干个,要求我们每个商品要买特定的个数,问我们使用优惠券能少花多少钱,注意优惠券可以重复使用,而且商品不能多买。 递归各种可用coupons组合。

[LeetCode#670] Maximum Swap 最大置换 Given a non-negative integer, you could swap two digits at most once to get the maximum valued number. Return the maximum valued number you could get. Example 1: Input: 2736 Output: 7236 Explanation: Swap the number 2 and the number 7. Example 2: Input: 9973 Output: 9973 Explanation: No swap. Note: The given number is in the range [0, 108]

有一次机会可以置换该数字中的任意两位,让我们返回置换后的最大值 #1 brute force 将所有可能的置换都进行一遍,然后更新结果res,取其中较大的数字 #2 最好的高位上的小数字和低位上的大数字进行置换:需要找到每个数字右边的最大数字(包括其自身) #3 思路类似#2,建了十个桶,分别代表数字0到9,每个桶存该数字出现的最后一个位置,也就是低位。从开头开始遍历数字上的每位上的数字,然后从大桶开始遍历,如果该大桶的数字对应的位置大于当前数字的位置,说明低位的数字要大于当前高位上的数字,那么直接交换这两个数字返回即可

[LeetCode#685] Redundant Connection II 冗余的连接之二 In this problem, a rooted tree is a directed graph such that, there is exactly one node (the root) for which all other nodes are descendants of this node, plus every node has exactly one parent, except for the root node which has no parents. The given input is a directed graph that started as a rooted tree with N nodes (with distinct values 1, 2, ..., N), with one additional directed edge added. The added edge has two different vertices chosen from 1 to N, and was not an edge that already existed. The resulting graph is given as a 2D-array of edges. Each element of edges is a pair [u, v] that represents a directed edge connecting nodes u and v, where u is a parent of child v. Return an edge that can be removed so that the resulting graph is a rooted tree of N nodes. If there are multiple answers, return the answer that occurs last in the given 2D-array. Example 1: Input: [[1,2], [1,3], [2,3]] Output: [2,3] Explanation: The given directed graph will be like this: 1 / \ v v 2-->3 Example 2: Input: [[1,2], [2,3], [3,4], [4,1], [1,5]] Output: [4,1] Explanation: The given directed graph will be like this: 5 <- 1 -> 2 ^ | | v 4 <- 3 Note: The size of the input 2D-array will be between 3 and 1000. Every integer represented in the 2D-array will be between 1 and N, where N is the size of the input array.

有向图 第一种:无环,但是有结点入度为2的结点(结点3) [[1,2], [1,3], [2,3]], return [2, 3]。 1 / \ v v 2-->3 第二种:有环,没有入度为2的结点 [[1,2], [2,3], [3,4], [4,1], [1,5]], return [4, 1] 5 <- 1 -> 2 ^ | | v 4 <- 3 第三种:有环,且有入度为2的结点(结点1) [[1,2],[2,3],[3,1],[4,1]], return [3,1] 4 / v 1 / ^ v \ 2 -->3 先来找入度为2的点,如果有的话,那么我们将当前产生入度为2的后加入的那条边标记为second,前一条边标记为first。我们废掉second,开始查环 当我们找到了环之后,如果first不存在,为情况二,返回最后成环的边 如果first存在,说明是第三种情况,我们返回first。 如果没有环存在,说明是第一种情况,我们返回second https://blog.csdn.net/u011934885/article/details/78705797 [Mine]目标是一个正常的树,冗余边破坏树,有两种可能,一是入度变为2,另外是出现环。 那么,我们先找入度为2,如果有,废掉第二个。然后检查环。 如果没环,且之前有入度为2,说明废对了,现在没入度2,也没环了。 如果有环,且之前有入度为2,那说明,应该废入度为2的另一个边。 如果有环,且没有入度为2,那就废掉成环的最后那个边

[LeetCode#635] Design Log Storage System 设计日志存储系统 You are given several logs that each log contains a unique id and timestamp. Timestamp is a string that has the following format: Year:Month:Day:Hour:Minute:Second, for example, 2017:01:01:23:59:59. All domains are zero-padded decimal numbers. Design a log storage system to implement the following functions: void Put(int id, string timestamp): Given a log's unique id and timestamp, store the log in your storage system. int[] Retrieve(String start, String end, String granularity): Return the id of logs whose timestamps are within the range from start to end. Start and end all have the same format as timestamp. However, granularity means the time level for consideration. For example, start = "2017:01:01:23:59:59", end = "2017:01:02:23:59:59", granularity = "Day", it means that we need to find the logs within the range from Jan. 1st 2017 to Jan. 2nd 2017. Example 1: put(1, "2017:01:01:23:59:59"); put(2, "2017:01:01:22:59:59"); put(3, "2016:01:01:00:00:00"); retrieve("2016:01:01:01:01:01","2017:01:01:23:00:00","Year"); // return [1,2,3], because you need to return all logs within 2016 and 2017. retrieve("2016:01:01:01:01:01","2017:01:01:23:00:00","Hour"); // return [1,2], because you need to return all logs start from 2016:01:01:01 to 2017:01:01:23, where log 3 is left outside the range. Note: There will be at most 300 operations of Put or Retrieve. Year ranges from [2000,2017]. Hour ranges from [00,23]. Output for Retrieve has no order required.

本题的难点了,如何能正确的在时间范围内取出日志。由于精确度的存在,比如精确度是Day,那么我们就不关心后面的时分秒是多少了,只需要比到天就行了。判断是否在给定的时间范围内的方法也很简单,看其是否大于起始时间,且小于结束时间,我们甚至可以直接用字符串相比较,不用换成秒啥的太麻烦。所以我们可以根据时间精度确定要比的子字符串的位置,然后直接相比就行了。

[LeetCode#666] Path Sum IV 二叉树的路径和之四 If the depth of a tree is smaller than 5, then this tree can be represented by a list of three-digits integers. For each integer in this list: The hundreds digit represents the depth D of this node, 1 <= D <= 4. The tens digit represents the position P of this node in the level it belongs to, 1 <= P <= 8. The position is the same as that in a full binary tree. The units digit represents the value V of this node, 0 <= V <= 9. Given a list of ascending three-digits integers representing a binary with the depth smaller than 5. You need to return the sum of all paths from the root towards the leaves. Example 1: Input: [113, 215, 221] Output: 12 Explanation: The tree that the list represents is: 3 / \ 5 1 The path sum is (3 + 5) + (3 + 1) = 12. Example 2: Input: [113, 221] Output: 4 Explanation: The tree that the list represents is: 3 \ 1 The path sum is (3 + 1) = 4.

树的存储方式比较特别,并没有专门的数结点,而是使用一个三位数字来存的,百位数是该结点的深度,十位上是该结点在某一层中的位置,个位数是该结点的结点值。 用其他的数据结构代替。比如我们可以将每个结点的位置信息和结点值分离开,然后建立两者之间的映射。比如我们可以将百位数和十位数当作key,将个位数当作value,建立映射。 #1 先序递归遍历 #2 层序迭代遍历

[LeetCode#679] 24 Game 二十四点游戏 You have 4 cards each containing a number from 1 to 9. You need to judge whether they could operated through *, /, +, -, (, )to get the value of 24. Example 1: Input: [4, 1, 8, 7] Output: True Explanation: (8-4) * (7-1) = 24 Example 2: Input: [1, 2, 1, 2] Output: False Note: The division operator / represents real division, not integer division. For example, 4 / (1 - 2/3) = 12. Every operation done is between two numbers. In particular, we cannot use - as a unary operator. For example, with [1, 1, 1, 1] as input, the expression -1 - 1 - 1 - 1 is not allowed. You cannot concatenate numbers together. For example, if the input is [1, 2, 1, 2], we cannot write this as 12 + 12.

每个人发四张牌,看谁最快能算出24 加法和乘法对于两个数字的前后顺序没有影响,但是减法和除法是有影响的,而且做除法的时候还要另外保证除数不能为零 #1 递归: 遍历任意两个数字,然后对于这两个数字,尝试各种加减乘除后得到一个新数字({p + q, p - q, q - p, p * q} and p/q , q/p),将这个新数字加到原数组中,记得原来的两个数要移除掉,然后调用递归函数进行计算 #2 递归,在减法和除法,不必交换,全排列时可以cover到。

[LeetCode#633] Sum of Square Numbers 平方数之和 Given a non-negative integer c, your task is to decide whether there're two integers a and b such that a2 + b2 = c. Example 1: Input: 5 Output: True Explanation: 1 * 1 + 2 * 2 = 5 Example 2: Input: 3 Output: False

求一个数是否能由两个平方数之和组成 #1 从c的平方根向0遍历,注意即使c不是平方数,sqrt(c)也会返回一个整型数i。然后我们判断如果i*i等于c,说明c就是个平方数,只要再凑个0,就是两个平方数之和,返回true;如果不等于的话,那么算出差值c - i*i,如果这个差值也是平方数的话,返回true。遍历结束后返回false for (int i = sqrt(c); i >= 0; --i) { if (i * i == c) return true; int d = c - i * i, t = sqrt(d); if (t * t == d) return true; } #2 集合set,从0遍历到c的平方根,对于每个i*i,都加入集合set中,然后计算c - i*i,如果这个差值也在集合set中,返回true,遍历结束返回false #3 用a和b代表了左右两个范围,分别为0和c的平方根,然后while循环遍历,如果a*a + b*b刚好等于c,那么返回true;如果小于c,则a增大1;反之如果大于c,则b自减1 [Mine]所有知道两数关系,求两数可能个数的问题,都是按住一个数,求另外一个数

[LeetCode#692] Top K Frequent Words 前K个高频词 Given a non-empty list of words, return the k most frequent elements. Your answer should be sorted by frequency from highest to lowest. If two words have the same frequency, then the word with the lower alphabetical order comes first. Example 1: Input: ["i", "love", "leetcode", "i", "love", "coding"], k = 2 Output: ["i", "love"] Explanation: "i" and "love" are the two most frequent words. Note that "i" comes before "love" due to a lower alphabetical order. Example 2: Input: ["the", "day", "is", "sunny", "the", "the", "the", "sunny", "is", "is"], k = 4 Output: ["the", "is", "sunny", "day"] Explanation: "the", "is", "sunny" and "day" are the four most frequent words, with the number of occurrence being 4, 3, 2 and 1 respectively. Note: You may assume k is always valid, 1 ≤ k ≤ number of unique elements. Input words contain only lowercase letters. Follow up: Try to solve it in O(n log k) time and O(n) extra space. Can you solve it in O(n) time with only O(k) extra space?

求前K个高频词,对于出现频率相同的单词,需要按照字母顺序来排。 #1 最大堆和桶排序 对priority_queue的排序机制进行自定义 #2 堆排序的思路,这里我们用map,来建立次数和出现该次数所有单词的集合set之间的映射,这里也利用了set能自动排序的特性 and map是从小到大排序的

[LeetCode#681] Next Closest Time 下一个最近时间点 Given a time represented in the format "HH:MM", form the next closest time by reusing the current digits. There is no limit on how many times a digit can be reused. You may assume the given input string is always valid. For example, "01:34", "12:09" are all valid. "1:34", "12:9" are all invalid. Example 1: Input: "19:34" Output: "19:39" Explanation: The next closest time choosing from digits 1, 9, 3, 4, is 19:39, which occurs 5 minutes later. It is not 19:33, because this occurs 23 hours and 59 minutes later. Example 2: Input: "23:59" Output: "22:22" Explanation: The next closest time choosing from digits 2, 3, 5, 9, is 22:22. It may be assumed that the returned time is next day's time since it is smaller than the input time numerically.

求最近的下一个时间点,规定了不能产生新的数字,当下个时间点超过零点时,就当第二天的时间 #1 Set + 排序。从低位到高位,替换 #2 可以从当前时间点开始,遍历一天的时间,也就是接下来的1440个时间点,得到一个新的整型时间点后,我们按位来更新结果res,对于每个更新的数字字符,看其是否在原时间点字符中存在,如果不存在,直接break,然后开始遍历下一个时间点,如果四个数字都成功存在了,那么将当前时间点中间夹上冒号返回即可

[LeetCode#714] Best Time to Buy and Sell Stock with Transaction Fee 买股票的最佳时间含交易费 Your are given an array of integers prices, for which the i-th element is the price of a given stock on day i; and a non-negative integer fee representing a transaction fee. You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction. You may not buy more than 1 share of a stock at a time (ie. you must sell the stock share before you buy again.) Return the maximum profit you can make. Example 1: Input: prices = [1, 3, 2, 8, 4, 9], fee = 2 Output: 8 Explanation: The maximum profit can be achieved by: Buying at prices[0] = 1 Selling at prices[3] = 8 Buying at prices[4] = 4 Selling at prices[5] = 9 The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8. Note: 0 < prices.length <= 50000. 0 < prices[i] < 50000. 0 <= fee < 50000.

没有交易次数限制。有了交易费,所以当卖出的利润小于交易费的时候,我们就不应该卖了,不然亏了。 #1 DP 本质其实是个三维dp数组,由于第三维只有两种情况,卖出和保留,而且第二维交易的次数在这道题中没有限制,所以我们用两个一维数组就可以了 sold[i]表示第i天卖掉股票此时的最大利润, hold[i]表示第i天保留手里的股票此时的最大利润。 sold[i] = max(sold[i - 1], hold[i - 1] + prices[i] - fee); hold[i] = max(hold[i - 1], sold[i - 1] - prices[i]); #2 优化空间,缩减两个一维到两个变量

[LeetCode#682] Baseball Game 棒球游戏 You're now a baseball game point recorder. Given a list of strings, each string can be one of the 4 following types: Integer (one round's score): Directly represents the number of points you get in this round. "+" (one round's score): Represents that the points you get in this round are the sum of the last two validround's points. "D" (one round's score): Represents that the points you get in this round are the doubled data of the last valid round's points. "C" (an operation, which isn't a round's score): Represents the last valid round's points you get were invalid and should be removed. Each round's operation is permanent and could have an impact on the round before and the round after. You need to return the sum of the points you could get in all the rounds. Example 1: Input: ["5","2","C","D","+"] Output: 30 Explanation: Round 1: You could get 5 points. The sum is: 5. Round 2: You could get 2 points. The sum is: 7. Operation 1: The round 2's data was invalid. The sum is: 5. Round 3: You could get 10 points (the round 2's data has been removed). The sum is: 15. Round 4: You could get 5 + 10 = 15 points. The sum is: 30. Example 2: Input: ["5","-2","4","C","D","9","+","+"] Output: 27 Explanation: Round 1: You could get 5 points. The sum is: 5. Round 2: You could get -2 points. The sum is: 3. Round 3: You could get 4 points. The sum is: 7. Operation 1: The round 3's data is invalid. The sum is: 3. Round 4: You could get -4 points (the round 3's data has been removed). The sum is: -1. Round 5: You could get 9 points. The sum is: 8. Round 6: You could get -4 + 9 = 5 points. The sum is 13. Round 7: You could get 9 + 5 = 14 points. The sum is 27. Note: The size of the input list will be between 1 and 1000. Every integer represented in the list will be between -30000 and 30000.

直接按照题目的描述来分情况处理即可 if (op == "+") { v.push_back(v.back() + v[v.size() - 2]); } else if (op == "D") { v.push_back(2 * v.back()); } else if (op == "C") { v.pop_back(); } else { v.push_back(stoi(op)); }

[LeetCode#675] Cut Off Trees for Golf Event 为高尔夫赛事砍树 You are asked to cut off trees in a forest for a golf event. The forest is represented as a non-negative 2D map, in this map: 0 represents the obstacle can't be reached. 1 represents the ground can be walked through. The place with number bigger than 1 represents a tree can be walked through, and this positive number represents the tree's height. You are asked to cut off all the trees in this forest in the order of tree's height - always cut off the tree with lowest height first. And after cutting, the original place has the tree will become a grass (value 1). You will start from the point (0, 0) and you should output the minimum steps you need to walk to cut off all the trees. If you can't cut off all the trees, output -1 in that situation. You are guaranteed that no two trees have the same height and there is at least one tree needs to be cut off. Example 1: Input: [ [1,2,3], [0,0,4], [7,6,5] ] Output: 6 Example 2: Input: [ [1,2,3], [0,0,0], [7,6,5] ] Output: -1 Example 3: Input: [ [2,3,4], [0,0,5], [8,7,6] ] Output: 6 Explanation: You started from the point (0,0) and you can cut off the tree in (0,0) directly without walking. Hint: size of the given matrix will not exceed 50x50.

砍掉所有高度大于1的树,而且要求是按顺序从低到高来砍。其实是求任意两点之间的最短距离 对高度相邻的两棵树之间调用一个BFS a)按照树高排序 b)BFS找当前位置到下一树之间的最短距离

[LeetCode#722] Remove Comments 移除注释 Given a C++ program, remove comments from it. The program source is an array where source[i] is the i-th line of the source code. This represents the result of splitting the original source code string by the newline character \n. In C++, there are two types of comments, line comments, and block comments. The string // denotes a line comment, which represents that it and rest of the characters to the right of it in the same line should be ignored. The string /* denotes a block comment, which represents that all characters until the next (non-overlapping) occurrence of */ should be ignored. (Here, occurrences happen in reading order: line by line from left to right.) To be clear, the string /*/ does not yet end the block comment, as the ending would be overlapping the beginning. The first effective comment takes precedence over others: if the string // occurs in a block comment, it is ignored. Similarly, if the string /* occurs in a line or block comment, it is also ignored. If a certain line of code is empty after removing comments, you must not output that line: each string in the answer list will be non-empty. There will be no control characters, single quote, or double quote characters. For example, source = "string s = "/* Not a comment. */";" will not be a test case. (Also, nothing else such as defines or macros will interfere with the comments.) It is guaranteed that every open block comment will eventually be closed, so /* outside of a line or block comment always starts a new comment. Finally, implicit newline characters can be deleted by block comments. Please see the examples below for details. After removing the comments from the source code, return the source code in the same format. Example 1: Input: source = ["/*Test program */", "int main()", "{ ", " // variable declaration ", "int a, b, c;", "/* This is a test", " multiline ", " comment for ", " testing */", "a = b + c;", "}"] The line by line code is visualized as below: /*Test program */ int main() { // variable declaration int a, b, c; /* This is a test multiline comment for testing */ a = b + c; } Output: ["int main()","{ "," ","int a, b, c;","a = b + c;","}"] The line by line code is visualized as below: int main() { int a, b, c; a = b + c; } Explanation: The string /* denotes a block comment, including line 1 and lines 6-9. The string // denotes line 4 as comments. Example 2: Input: source = ["a/*comment", "line", "more_comment*/b"] Output: ["ab"] Explanation: The original source string is "a/*comment\nline\nmore_comment*/b", where we have bolded the newline characters. After deletion, the implicit newline characters are deleted, leaving the string "ab", which when delimited by newline characters becomes ["ab"]. Note: The length of source is in the range [1, 100]. The length of source[i] is in the range [0, 80]. Every open block comment is eventually closed. There are no single-quote, double-quote, or control characters in the source code.

移除代码中的注释部分,标识符"//"和"/*",注意它们两者之间存在覆盖的关系,谁在前面谁work 按行逐字符判断,用变量记录是否/*开始

[LeetCode#660] Remove 9 移除9 Start from integer 1, remove any integer that contains 9 such as 9, 19, 29... So now, you will have a new integer sequence: 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, ... Given a positive integer n, you need to return the n-th integer after removing. Note that 1 will be the first integer. Example 1: Input: 9 Output: 10 Hint: n will not exceed 9 x 10^8.

移除所有包含数字9的数字,然后得到一个新的数列,给我们一个数字n,让我们求在这个新的数组中第n个数字 8的下一位就是10了,18的下一位是20,88的下一位是100,实际上这就是九进制的数字的规律 #1 十进制数n转为九进制数 #2 数字9是个特例,可以用上面的巧妙的解法,但如果要移除1到8中间的任意一个呢? a)非移除数开头的其他9行,各移除1个,移除数开头的10个都要移除,所以就有10+9=19个 b)数字a跟要移除数d之间的关系。有三种关系,分别是小于,等于,大于 当 a < d 时,每10个数中只含有一个d,所以就要移除a个d就行了,a * 19个,然后再加上下一位上移除的值 当 a = d 时,分成小于的部分,和等于的部分:m % 10^i + 1 当a > d 时,通过a - 1来算,实际上是情况1的值再加上 10^i 个数

[LeetCode#669] Trim a Binary Search Tree 修剪一棵二叉搜索树 Given a binary search tree and the lowest and highest boundaries as L and R, trim the tree so that all its elements lies in [L, R] (R >= L). You might need to change the root of the tree, so the result should return the new root of the trimmed binary search tree. Example 1: Input: 1 / \ 0 2 L = 1 R = 2 Output: 1 \ 2 Example 2: Input: 3 / \ 0 4 \ 2 / 1 L = 1 R = 3 Output: 3 / 2 / 1

给了个边界范围[L, R], 所有不在这个范围内的结点应该被移除掉,但是仍需要保留二叉搜索树的性质,即左<根<右 如果root为空,那么直接返回空即可。 如果根结点值小于L,那么返回对其右子结点调用递归函数的值; 如果根结点大于R,那么返回对其左子结点调用递归函数的值。 如果根结点在范围内,将其左子结点更新为对其左子结点调用递归函数的返回值,同样,将其右子结点更新为对其右子结点调用递归函数的返回值。最后返回root即可 #1 递归 #2 迭代

[LeetCode#605] Can Place Flowers 可以放置花 Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, flowers cannot be planted in adjacent plots - they would compete for water and both would die. Given a flowerbed (represented as an array containing 0 and 1, where 0 means empty and 1 means not empty), and a number n, return if n new flowers can be planted in it without violating the no-adjacent-flowers rule. Example 1: Input: flowerbed = [1,0,0,0,1], n = 1 Output: True Example 2: Input: flowerbed = [1,0,0,0,1], n = 2 Output: False Note: The input array won't violate no-adjacent-flowers rule. The input array size is in the range of [1, 20000]. n is a non-negative integer which won't exceed the input array size.

给了我们一个01数组,其中1表示已经放了花,0表示可以放花的位置,但是有个限制条件是不能有相邻的花 #1 想通过计算连续0的个数,然后直接算出能放花的个数,就必须要对边界进行处理,处理方法是如果首位置是0,那么前面再加上个0,如果末位置是0,就在最后面再加上个0。这样处理之后我们就默认连续0的左右两边都是1了,这样如果有k个连续0,那么就可以通过(k-1)/2来快速计算出能放的花的数量 #2 直接通过修改flowerbed的值来做,我们遍历花床,如果某个位置为0,我们就看其前面一个和后面一个位置的值,注意处理首位置和末位置的情况,如果pre和next均为0,那么说明当前位置可以放花,我们修改flowerbed的值,并且n自减1,最后看n是否小于等于0 #3 为了不特殊处理首末位置,直接先在首尾各加了一个0,然后就三个三个的来遍历,如果找到了三个连续的0,那么n自减1,i自增1,这样相当于i一下向后跨了两步

[LeetCode#648] Replace Words 替换单词 In English, we have a concept called root, which can be followed by some other words to form another longer word - let's call this word successor. For example, the root an, followed by other, which can form another word another. Now, given a dictionary consisting of many roots and a sentence. You need to replace all the successor in the sentence with the root forming it. If a successor has many roots can form it, replace it with the root with the shortest length. You need to output the sentence after the replacement. Example 1: Input: dict = ["cat", "bat", "rat"] sentence = "the cattle was rattled by the battery" Output: "the cat was rat by the bat" Note: The input will only have lower-case letters. 1 <= dict words number <= 1000 1 <= sentence words number <= 1000 1 <= root length <= 100 1 <= sentence words length <= 1000

给了我们一个前缀字典,又给了一个句子,让我们将句子中较长的单词换成其前缀(如果在前缀字典中存在的话)。 #1 将首字母相同的前缀都放到同一个数组中,总共需要26个数组。先按单词的长度来给所有的前缀排序,然后再依次加入对应的数组中,这样就可以保证短的前缀在前面。 #2 Trie / Prefix Tree 把所有的前缀都放到前缀树里面,而且在前缀的最后一个结点的地方将标示isWord设为true,表示从根节点到当前结点是一个前缀,然后我们在遍历单词中的每一个字母,我们都在前缀树查找,如果当前字母对应的结点的表示isWord是true,我们就返回这个前缀,如果当前字母对应的结点在前缀树中不存在,我们就返回原单词,这样就能完美的解决问题了。

[LeetCode#719] Find K-th Smallest Pair Distance 找第K小的数对儿距离 Given an integer array, return the k-th smallest distance among all the pairs. The distance of a pair (A, B) is defined as the absolute difference between A and B. Example 1: Input: nums = [1,3,1] k = 1 Output: 0 Explanation: Here are all the pairs: (1,3) -> 2 (1,1) -> 0 (3,1) -> 2 Then the 1st smallest distance pair is (1,1), and its distance is 0. Note: 2 <= len(nums) <= 10000. 0 <= nums[i] < 1000000. 1 <= k <= len(nums) * (len(nums) - 1) / 2.

给了我们一个数组,让我们找第k小的数对儿距离,数对儿距离就是任意两个数字之间的绝对值差。 #1 brute force+桶排序(数字的大小范围,不会超过一百万,所以我们就建立一百万个桶,每个桶存此间距出现的次数) #2 二分搜索:二分法的判定条件不是简单的大小关系,而是可以抽离出子函数的情况 二分确定一个中间数,然后找到所有小于等于这个中间数的距离个数,用其跟k比较来确定折半的方向。 数组排序,二分搜索的起始left为0,结束位置right为最大距离,即排序后的数字最后一个元素减去首元素。然后进入while循环,算出中间值mid [Mine]在可能的最小最大间距中用折半查找去找比mid小的间距个数(递增数列,滑动窗口),然后调整left/right去逼近个数为k int mid = left + (right - left) / 2, cnt = 0, start = 0; for (int i = 0; i < n; ++i) { while (start < n && nums[i] - nums[start] > mid) ++start; cnt += i - start; } if (cnt < k) left = mid + 1; else right = mid;

[LeetCode#634] Find the Derangement of An Array 找数组的错排 In combinatorial mathematics, a derangement is a permutation of the elements of a set, such that no element appears in its original position. There's originally an array consisting of n integers from 1 to n in ascending order, you need to find the number of derangement it can generate. Also, since the answer may be very large, you should return the output mod 109 + 7. Example 1: Input: 3 Output: 2 Explanation: The original array is [1,2,3]. The two derangements are [2,3,1] and [3,1,2]. Note: n is in the range of [1, 106].

给了我们一个数组,让我们求其错排的个数,所谓错排就是1到n中的每个数字都不在其原有的位置上,全部打乱了,问能有多少种错排的方式。 想n = 4时该怎么求,我们假设把4排在了第k位,这里我们就让k = 3吧,那么我们就把4放到了3的位置,变成了: x x 4 x 我们看被4占了位置的3,应该放到哪里,这里分两种情况,如果3放到了4的位置,那么有: x x 4 3 那么此时4和3的位置都确定了,实际上只用排1和2了,那么就相当于只排1和2,就是dp[2]的值,是已知的。那么再来看第二种情况,3不在4的位置,那么此时我们把4去掉的话,就又变成了: x x x 这里3不能放在第3个x的位置,在去掉4之前,这里是移动4之前的4的位置,那么实际上这又变成了排1,2,3的情况了,就是dp[3]的值。 再回到最开始我们选k的时候,我们当时选了k = 3,其实k可以等于1,2,3,也就是有三种情况,所以dp[4] = 3 * (dp[3] + dp[2])。 那么递推公式也就出来了: dp[i] = (i - 1) * (dp[i - 1] + dp[i - 2]) 解释#2 dp[n]表示到n能形成的Derangement,dp[n+1]无非是多出来一个数n+1, (1)n+1可以与0..n之间的任意1个数交换(可以确保没有重复,因为不同的Derangement至少有2位差别,与n+1交换一位,最后还是不同的); (2)前n位数也不一定严格要求是Derangement,可以存在一位异常,及value等于index,此时等价于dp[n-1](n+1和这个异常位交换,其他数字的组合是dp[n-1]) 所以dp[n+1]=n*(dp[n]+dp[n-1]) #Further: 因为当前值只跟前两个值有关系,所以没必要保留整个数组,只用两个变量来记录前两个值,并每次更新一下就好了 #3 新递推公式: dp[i] = i * dp[i - 1] + (-1)^i

[LeetCode#721] Accounts Merge 账户合并 Given a list accounts, each element accounts[i] is a list of strings, where the first element accounts[i][0] is a name, and the rest of the elements are emails representing emails of the account. Now, we would like to merge these accounts. Two accounts definitely belong to the same person if there is some email that is common to both accounts. Note that even if two accounts have the same name, they may belong to different people as people could have the same name. A person can have any number of accounts initially, but all of their accounts definitely have the same name. After merging the accounts, return the accounts in the following format: the first element of each account is the name, and the rest of the elements are emails in sorted order. The accounts themselves can be returned in any order. Example 1: Input: accounts = [["John", "[email protected]", "[email protected]"], ["John", "[email protected]"], ["John", "[email protected]", "[email protected]"], ["Mary", "[email protected]"]] Output: [["John", '[email protected]', '[email protected]', '[email protected]'], ["John", "[email protected]"], ["Mary", "[email protected]"]] Explanation: The first and third John's are the same person as they have the common email "[email protected]". The second John and Mary are different people as none of their email addresses are used by other accounts. We could return these lists in any order, for example the answer [['Mary', '[email protected]'], ['John', '[email protected]'], ['John', '[email protected]', '[email protected]', '[email protected]']] would still be accepted. Note: The length of accounts will be in the range [1, 1000]. The length of accounts[i] will be in the range [1, 10]. The length of accounts[i][j] will be in the range [1, 30].

给了我们一堆人名和邮箱,一个名字可能有多个邮箱,但是一个邮箱只属于一个人,让我们把同一个人的邮箱都合并到一起,名字相同不一定是同一个人,只有当两个名字有相同的邮箱,才能确定是同一个人 #1 并查集Union Find #2 BFS 建立了每个邮箱和其所有出现的账户数组之间的映射 遍历账户,通过邮箱edge,搜索相关连的账户。

[LeetCode#611] Valid Triangle Number 合法的三角形个数 Given an array consists of non-negative integers, your task is to count the number of triplets chosen from the array that can make triangles if we take them as side lengths of a triangle. Example 1: Input: [2,2,3,4] Output: 3 Explanation: Valid combinations are: 2,3,4 (using the first 2) 2,3,4 (using the second 2) 2,2,3 Note: The length of the given array won't exceed 1000. The integers in the given array are in the range of [0, 1000].

给了我们一堆数字,问我们能组成多少个正确的三角形 任意两条边之和要大于第三边,三个数字中如果较小的两个数字之和大于第三个数字,那么任意两个数字之和都大于第三个数字 #1 O(logN*N^2) 先确定前两个数,将这两个数之和sum作为目标值,然后用二分查找法来快速确定第一个小于目标值的数。找到这个临界值,那么这之前一直到j的位置之间的数都满足题意,直接加起来即可 [Mine]按住两边,找第三边范围 #2 O(N^2) 排序之后,从数字末尾开始往前遍历,将left指向首数字,将right之前遍历到的数字的前面一个数字,然后如果left小于right就进行循环,循环里面判断如果left指向的数加上right指向的数大于当前的数字的话,那么right到left之间的数字都可以组成三角形 [Mine]一值确定,也就确定了另外两值和的最小值。此时再按住一个值(right),就能求left的范围 #2比#1优化在,当确定了i和right,找到合适的left之后,right--,并没有再从left=0开始找,而是直接用上次的left值。这是因为比当前left小的数加上比right大的数都小于i,不符合条件

[LeetCode#650] 2 Keys Keyboard 两键的键盘 Initially on a notepad only one character 'A' is present. You can perform two operations on this notepad for each step: Copy All: You can copy all the characters present on the notepad (partial copy is not allowed). Paste: You can paste the characters which are copied last time. Given a number n. You have to get exactly n 'A' on the notepad by performing the minimum number of steps permitted. Output the minimum number of steps to get n 'A'. Example 1: Input: 3 Output: 3 Explanation: Intitally, we have one character 'A'. In step 1, we use Copy All operation. In step 2, we use Paste operation to get 'AA'. In step 3, we use Paste operation to get 'AAA'. Note: The n will be in the range [1, 1000].

给了我们复制和粘贴这两个按键,然后给了我们了一个A,我们的目标时利用这两个键来打印出n个A,注意复制的时候时全部复制,不能选择部分来复制,然后复制和粘贴都算操作步骤,问我们打印出n个A需要多少步操作 递归或DP,找规律: 对于任意一个n(除了1以外),我们最差的情况就是用n步,不会再多于n步,但是有可能是会小于n步的 小模块的长度必须要能整除n,这样才能拆分。对于n=6,我们其实还可先拼出AA,然后再复制一次,粘贴两次,得到的还是5。 找出n的所有因子,然后这个因子可以当作模块的个数,我们再算出模块的长度n/i,调用递归,加上模块的个数i来更新结果res即可 if (i % j == 0) { dp[i] = min(dp[i], dp[j] + i / j); }

[LeetCode#623] Add One Row to Tree 二叉树中增加一行 Given the root of a binary tree, then value v and depth d, you need to add a row of nodes with value v at the given depth d. The root node is at depth 1. The adding rule is: given a positive integer depth d, for each NOT null tree nodes N in depth d-1, create two tree nodes with value v as N's left subtree root and right subtree root. And N's original left subtree should be the left subtree of the new left subtree root, its original right subtree should be the right subtree of the new right subtree root. If depth d is 1 that means there is no depth d-1 at all, then create a tree node with value v as the new root of the whole original tree, and the original tree is the new root's left subtree. Example 1: Input: A binary tree as following: 4 / \ 2 6 / \ / 3 1 5 v = 1 d = 2 Output: 4 / \ 1 1 / \ 2 6 / \ / 3 1 5 Example 2: Input: A binary tree as following: 4 / 2 / \ 3 1 v = 1 d = 3 Output: 4 / 2 / \ 1 1 / \ 3 1 Note: The given d is in range [1, maximum depth of the given tree + 1]. The given binary tree has at least one tree node.

给二叉树增加一行,给了我们需要增加的值,还有需要增加的位置深度 #1 层序遍历 #2 递归

[LeetCode#667] Beautiful Arrangement II 优美排列之二 Given two integers n and k, you need to construct a list which contains n different positive integers ranging from 1 to n and obeys the following requirement: Suppose this list is [a1, a2, a3, ... , an], then the list [|a1 - a2|, |a2 - a3|, |a3 - a4|, ... , |an-1 - an|] has exactly k distinct integers. If there are multiple answers, print any of them. Example 1: Input: n = 3, k = 1 Output: [1, 2, 3] Explanation: The [1, 2, 3] has three different positive integers ranging from 1 to 3, and the [1, 1] has exactly 1 distinct integer: 1. Example 2: Input: n = 3, k = 2 Output: [1, 3, 2] Explanation: The [1, 3, 2] has three different positive integers ranging from 1 to 3, and the [2, 1] has exactly 2 distinct integers: 1 and 2. Note: The n and k are in the range 1 <= k < n <= 104.

给我们了一个数字n和一个数字k,让找出一种排列方式,使得1到n组成的数组中相邻两个数的差的绝对值正好有k种。 当n=8, #1 先按照这种最小最大数相邻的方法排列,每排一个,k自减1,当k减到1的时候,后面的排列方法只要按照生序的方法排列,就不会产生不同的差的绝对值,这种算法的时间复杂度是O(n),

[LeetCode#658] Find K Closest Elements 寻找K个最近元素 Given a sorted array, two integers k and x, find the k closest elements to x in the array. The result should also be sorted in ascending order. If there is a tie, the smaller elements are always preferred. Example 1: Input: [1,2,3,4,5], k=4, x=3 Output: [1,2,3,4] Example 2: Input: [1,2,3,4,5], k=4, x=-1 Output: [1,2,3,4] Note: The value k is positive and will always be smaller than the length of the sorted array. Length of the given array is positive and will not exceed 104 Absolute value of elements in the array and x will not exceed 104

给我们了一个数组,还有两个变量k和x。让我们找数组中离x最近的k个元素,而且说明了数组是有序的,如果两个数字距离x相等的话,取较小的那个。 #1 相当于在长度为n的数组中去掉n-k个数字,而且去掉的顺序肯定是从两头开始去,因为距离x最远的数字肯定在首尾出现。每次比较首尾两个数字跟x的距离,将距离大的那个数字删除,直到剩余的数组长度为k为止 #2 二分搜索法 每次比较的是mid位置和x的距离跟mid+k跟x的距离,以这两者的大小关系来确定二分法折半的方向,最后找到最近距离子数组的起始位置

[LeetCode#624] Maximum Distance in Arrays 数组中的最大距离 Given m arrays, and each array is sorted in ascending order. Now you can pick up two integers from two different arrays (each array picks one) and calculate the distance. We define the distance between two integers a and b to be their absolute difference |a-b|. Your task is to find the maximum distance. Example 1: Input: [[1,2,3], [4,5], [1,2,3]] Output: 4 Explanation: One way to reach the maximum distance 4 is to pick 1 in the first or third array and pick 5 in the second array. Note: Each given array will have at least 1 number. There will be at least two non-empty arrays. The total number of the integers in all the m arrays will be in the range of [2, 10000]. The integers in the m arrays will be in the range of [-10000, 10000].

给我们了一些数组,每个数组都是有序的,让我们从不同的数组中各取一个数字,使得这两个数字的差的绝对值最大,让我们求这个最大值。 差的绝对值最大的两个数字肯定是分别位于数组的首和尾 #1 一个最大堆,一个最小堆.,最大堆存每个数组的尾元素,最小堆存每个数组的首元素.如果最大的数字和最小的数字不在一个数组,那么直接返回二者的绝对差即可,如果在的话,那么要返回第二大数字和最小数字绝对差跟最大数字和第二小数字绝对差中的较大值 #2 用两个变量start和end分别表示当前遍历过的数组中最小的首元素,和最大的尾元素,那么每当我们遍历到一个新的数组时,只需计算新数组尾元素和start绝对差,跟end和新数组首元素的绝对差,取二者之间的较大值来更新结果res即可

[LeetCode#671] Second Minimum Node In a Binary Tree 二叉树中第二小的结点 Given a non-empty special binary tree consisting of nodes with the non-negative value, where each node in this tree has exactly two or zero sub-node. If the node has two sub-nodes, then this node's value is the smaller value among its two sub-nodes. Given such a binary tree, you need to output the second minimum value in the set made of all the nodes' value in the whole tree. If no such second minimum value exists, output -1 instead. Example 1: Input: 2 / \ 2 5 / \ 5 7 Output: 5 Explanation: The smallest value is 2, the second smallest value is 5. Example 2: Input: 2 / \ 2 2 Output: -1 Explanation: The smallest value is 2, but there isn't any second smallest value.

给该二叉树做了一些限制,比如对于任意一个结点,要么其没有子结点,要么就同时有两个子结点,而且父结点值是子结点值中较小的那个,当然两个子结点值可以相等。 根一定是first,目标是找second 递归或层序迭代,搜索second

[LeetCode#695] Max Area of Island 岛的最大面积 Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water. Find the maximum area of an island in the given 2D array. (If there is no island, the maximum area is 0.) Example 1: [[0,0,1,0,0,0,0,1,0,0,0,0,0], [0,0,0,0,0,0,0,1,1,1,0,0,0], [0,1,1,0,1,0,0,0,0,0,0,0,0], [0,1,0,0,1,1,0,0,1,0,1,0,0], [0,1,0,0,1,1,0,0,1,1,1,0,0], [0,0,0,0,0,0,0,0,0,0,1,0,0], [0,0,0,0,0,0,0,1,1,1,0,0,0], [0,0,0,0,0,0,0,1,1,0,0,0,0]] Given the above grid, return 6. Note the answer is not 11, because the island must be connected 4-directionally. Example 2: [[0,0,0,0,0,0,0,0]] Given the above grid, return 0. Note: The length of each dimension in the given grid does not exceed 50.

统计出每个岛的大小,再来更新结果res #1 DFS #2 BFS

[LeetCode#628] Maximum Product of Three Numbers 三个数字的最大乘积 Given an integer array, find three numbers whose product is maximum and output the maximum product. Example 1: Input: [1,2,3] Output: 6 Example 2: Input: [1,2,3,4] Output: 24 Note: The length of the given array will be in range [3,104] and all elements are in the range [-1000, 1000]. Multiplication of any three numbers in the input won't exceed the range of 32-bit signed integer.

要考虑到负数和0的情况 重点在于前半段是负数,后半段是正数,那么最好的情况肯定是两个最小的负数相乘得到一个正数,然后跟一个最大的正数相乘 #1 排序 sort(nums.begin(), nums.end()); int p = nums[0] * nums[1] * nums[n - 1]; return max(p, nums[n - 1] * nums[n - 2] * nums[n - 3]); #2 找出3个最大的数 || 找出一个最大的和两个最小的,相乘对比也能得到结果,而且是O(n)的时间复杂度

[LeetCode#686] Repeated String Match 重复字符串匹配 Given two strings A and B, find the minimum number of times A has to be repeated such that B is a substring of it. If no such solution, return -1. For example, with A = "abcd" and B = "cdabcdab". Return 3, because by repeating A three times ("abcdabcdabcd"), B is a substring of it; and B is not a substring of A repeated two times ("abcdabcd"). Note: The length of A and B will be between 1 and 10000.

让我们用字符串B来匹配字符串A,问字符串A需要重复几次,如果无法匹配,则返回-1 #1 先进行重复A,直到A的长度大于等于B,并且累计次数cnt,find找一下。 如果找不到,再加上一个A,find一下,来避免A="abc", B="cab" case

[LeetCode#630] Course Schedule III 课程清单之三 There are n different online courses numbered from 1 to n. Each course has some duration(course length) tand closed on dth day. A course should be taken continuously for t days and must be finished before or on the dth day. You will start at the 1st day. Given n online courses represented by pairs (t,d), your task is to find the maximal number of courses that can be taken. Example: Input: [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]] Output: 3 Explanation: There're totally 4 courses, but you can take 3 courses at most: First, take the 1st course, it costs 100 days so you will finish it on the 100th day, and ready to take the next course on the 101st day. Second, take the 3rd course, it costs 1000 days so you will finish it on the 1100th day, and ready to take the next course on the 1101st day. Third, take the 2nd course, it costs 200 days so you will finish it on the 1300th day. The 4th course cannot be taken now, since you will finish it on the 3300th day, which exceeds the closed date. Note: The integer 1 <= d, t, n <= 10,000. You can't take two courses simultaneously.

许多课程,每个课程有两个参数,第一个是课程的持续时间,第二个是课程的最晚结束日期,让我们求最多能上多少门课 按照结束时间的顺序来排序,遍历每个课程,对于每一个遍历到的课程,当前时间加上该课程的持续时间,然后将该持续时间放入优先数组中,然后我们判断如果当前时间大于课程的结束时间,说明这门课程无法被完成。目标是尽可能的多上课,既然非要去掉一门课,那肯定是去掉耗时最长的课,这样省下来的时间说不定能多上几门课呢,最后返回优先队列中元素的个数就是能完成的课程总数啦 [Mine]以结束时间排序,结束时间越早越急,要优先安排。如果后面课程安排不进去,由于目标是上课数目最多,所以将备选课程中耗时最长的删除(可能是刚刚要安排的课),这样相同的课程数目,总用时可能减少。 结束时间排序后,用大堆,进行贪婪算法,把堆中用时多的替换出来,尽量在堆中塞入更多的课程。

[LeetCode#659] Split Array into Consecutive Subsequences 将数组分割成连续子序列 You are given an integer array sorted in ascending order (may contain duplicates), you need to split them into several subsequences, where each subsequences consist of at least 3 consecutive integers. Return whether you can make such a split. Example 1: Input: [1,2,3,3,4,5] Output: True Explanation: You can split them into two consecutive subsequences : 1, 2, 3 3, 4, 5 Example 2: Input: [1,2,3,3,4,4,5,5] Output: True Explanation: You can split them into two consecutive subsequences : 1, 2, 3, 4, 5 3, 4, 5 Example 3: Input: [1,2,3,4,4,5] Output: False Note: The length of the input is in range of [1, 10000]

贪婪 第一个map用来建立数字和其出现次数之间的映射freq,第二个用来建立可以加在某个连续子序列后的数字及其可以出现的次数之间的映射need 1. 对于每个遍历到的数字,首先看其当前出现的次数,如果为0,则继续循环; 2. 如果need中存在这个数字的非0映射,那么表示当前的数字可以加到某个连的末尾,我们将当前数字的映射值自减1,然后将下一个连续数字的映射值加1,因为当[1,2,3]连上4后变成[1,2,3,4]之后,就可以连上5了 3. 如果不能连到其他子序列后面,我们来看其是否可以成为新的子序列的起点,可以通过看后面两个数字的映射值是否大于0,都大于0的话,说明可以组成3连儿,于是将后面两个数字的映射值都自减1,还有由于组成了3连儿,在need中将末尾的下一位数字的映射值自增1; 4. 如果上面情况都不满足,说明该数字是单牌,只能划单儿,直接返回false。 [Mine]通过两个map,在数字中找>3的顺子,找到一组,就划去一组,直到看看是否有单牌

[LeetCode#711] Number of Distinct Islands II 不同岛屿的个数之二 Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water. Count the number of distinct islands. An island is considered to be the same as another if they have the same shape, or have the same shape after rotation (90, 180, or 270 degrees only) or reflection (left/right direction or up/down direction). Example 1: 11000 10000 00001 00011 Given the above grid map, return 1. Notice that: 11 1 and 1 11 are considered same island shapes. Because if we make a 180 degrees clockwise rotation on the first island, then two islands will have the same shapes. Example 2: 11100 10001 01001 01110 Given the above grid map, return 2. Here are the two distinct islands: 111 1 and 1 1 Notice that: 111 1 and 1 111 are considered same island shapes. Because if we flip the first array in the up/down direction, then they have the same shapes. Note: The length of each dimension in the given grid does not exceed 50.

这次判断小岛是否相同加上了8个对应的变形(包括本身,翻转以及旋转等) https://blog.csdn.net/magicbean2/article/details/79282937 DFS + Set of Vector, Vector=8 varieties of each island. for (auto &p : a) { int x = p.first, y = p.second; ret[0].push_back(make_pair(x, y)); ret[1].push_back(make_pair(x, -y)); ret[2].push_back(make_pair(-x, y)); ret[3].push_back(make_pair(-x, -y)); ret[4].push_back(make_pair(y, x)); ret[5].push_back(make_pair(y, -x)); ret[6].push_back(make_pair(-y, x)); ret[7].push_back(make_pair(-y, -x)); }

[LeetCode#678] Valid Parenthesis String 验证括号字符串 Given a string containing only three types of characters: '(', ')' and '*', write a function to check whether this string is valid. We define the validity of a string by these rules: Any left parenthesis '(' must have a corresponding right parenthesis ')'. Any right parenthesis ')' must have a corresponding left parenthesis '('. Left parenthesis '(' must go before the corresponding right parenthesis ')'. '*' could be treated as a single right parenthesis ')' or a single left parenthesis '(' or an empty string. An empty string is also valid. Example 1: Input: "()" Output: True Example 2: Input: "(*)" Output: True Example 3: Input: "(*))" Output: True Note: The string size will be in the range [1, 100].

这道题只有小括号,不过还存在星号,星号可以当左括号,右括号,或空来使用,问我们能不能得到一个合法的括号字符串。 观察*) and *( #1 两个stack,分别存放左括号和星号的位置,遍历字符串,当遇到星号时,压入星号栈star,当遇到左括号时,压入左括号栈left, 当遇到右括号时,此时如果left和star均为空时,直接返回false;如果left不为空,则pop一个左括号来抵消当前的右括号;否则从star中取出一个星号当作左括号来抵消右括号。 当循环结束后,我们希望left中没有多余的左括号,就算有,我们可以尝试着用星号来抵消(注意* and 左括号位置) #2 DPS (*当作左括号,右括号,或空来使用) #3 两个计数: low表示在有左括号的情况下,将星号当作右括号时左括号的个数 high表示将星号当作左括号时左括号的个数。 当high小于0时,说明就算把星号都当作左括号了,还是不够抵消右括号,返回false。 当low大于0时,说明左括号的个数太多了,没有足够多的右括号来抵消,返回false。 for (char c : s) { if (c == '(') { ++low; ++high; } else if (c == ')') { if (low > 0) --low; --high; } else { if (low > 0) --low; ++high; } if (high < 0) return false; } return low == 0; [Mine]感觉#3,简化了#1的思想。 匹配过程中的合理情况是low>=0 and high>=0(可以有未配对的左括号,不能有未配对的右括号) 匹配结束时的合理情况是low=0 low是只看确实的左括号是否完全配对。不看星号"妄想"来的。保证左括号规则正确 high是确保右括号规则正确。 最后,high>=0保证了右括号规则,low=0保证所有确实的左括号都配对正确

[LeetCode#680] Valid Palindrome II 验证回文字符串之二 Given a non-empty string s, you may delete at most one character. Judge whether you can make it a palindrome. Example 1: Input: "aba" Output: True Example 2: Input: "abca" Output: True Explanation: You could delete the character 'c'. Note: The string will only contain lowercase characters a-z. The maximum length of the string is 50000.

这道题的字符串中只含有小写字母,而且这道题允许删除一个字符 写一个子函数来判断字符串中的某一个范围内的子字符串是否为回文串 当遇到不匹配的时候,删除左边的字符,或删除右边的字符,两种情况都要算一遍,只要有一种能返回true,那么结果就返回true

[LeetCode#632] Smallest Range 最小的范围 You have k lists of sorted integers in ascending order. Find the smallest range that includes at least one number from each of the k lists. We define the range [a,b] is smaller than range [c,d] if b-a < d-c or a < c if b-a == d-c. Example 1: Input:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]] Output: [20,24] Explanation: List 1: [4, 10, 15, 24,26], 24 is in range [20,24]. List 2: [0, 9, 12, 20], 20 is in range [20,24]. List 3: [5, 18, 22, 30], 22 is in range [20,24]. Note: The given list may contain duplicates, so ascending order means >= here. 1 <= k <= 3500 -105 <= value of elements <= 105. For Java users, please note that the input type has been changed to List<List<Integer>>. And after you reset the code template, you'll see this point.

这道题给了我们一些数组,都是排好序的,让我们求一个最小的范围,使得这个范围内至少会包括每个数组中的一个数字。 #1 合并成一个数组统一处理比较好,但是合并成一个大数组还需要保留其原属数组的序号,所以我们大数组中存pair对,同时保存数字和原数组的序号。然后我们重新按照数字大小进行排序,这样我们的问题实际上就转换成了求一个最小窗口,使其能够同时包括所有数组中的至少一个数字。 滑动窗口+hashmap统计同一数组在窗口中出现次数。 Similar to #76 Minimum Window Substring #2 curMax表示当前遇到的最大数字,用一个idx数组表示每个list中遍历到的位置,然后就是我们的优先队列(最小堆)了,里面放一个pair,是数字和其所属list组成的对儿。每个数组取第一个,生成pair,放入最小堆,更新当前最大值curMax。此时我们的queue中是每个list各有一个数字,由于是最小堆,所以最小的数字就在队首,再加上最大值curMax,就可以初始化结果res了 当某个list的数字遍历完了就结束循环,因为我们的范围要cover每个list至少一个数字。 [Mine]不用重新整体排序,利用各个数组已经排序好的前提。list保证了每个数组都会取到。最小堆保证在每个数组都取到的情况下,替换范围的下沿。

[LeetCode#662] Maximum Width of Binary Tree 二叉树的最大宽度 Given a binary tree, write a function to get the maximum width of the given tree. The width of a tree is the maximum width among all levels. The binary tree has the same structure as a full binary tree, but some nodes are null. The width of one level is defined as the length between the end-nodes (the leftmost and right most non-null nodes in the level, where the null nodes between the end-nodes are also counted into the length calculation. Example 1: Input: 1 / \ 3 2 / \ \ 5 3 9 Output: 4 Explanation: The maximum width existing in the third level with the length 4 (5,3,null,9). Example 2: Input: 1 / 3 / \ 5 3 Output: 2 Explanation: The maximum width existing in the third level with the length 2 (5,3). Example 3: Input: 1 / \ 3 2 / 5 Output: 2 Explanation: The maximum width existing in the second level with the length 2 (3,2). Example 4: Input: 1 / \ 3 2 / \ 5 9 / \ 6 7 Output: 8 Explanation:The maximum width existing in the fourth level with the length 8 (6,null,null,null,null,null,null,7). Note: Answer will in the range of 32-bit signed integer.

这里的最大宽度不是满树的时候的最大宽度,如果是那样的话,肯定是最后一层的结点数最多。这里的最大宽度应该是两个存在的结点中间可容纳的总的结点个数,中间的结点可以为空。 每一层中最左边和最右边的结点的位置 #1 完美二叉树:每一层的结点数就是2*n-1,那么每个结点的位置就是[1, 2*n-1]中的一个,假设某个结点的位置是i,那么其左右子结点的位置可以直接算出来,为2*i和2*i+1 [Mine]利用以上特性,定义一个动态扩展数组,数组长度为当前遍历的最大层数(树高),递归先根遍历,递归传递每个节点在完美二叉树时的index,在数组中记录每层第一个节点的index,之后计算此层后续节点对第一节点index的差值,更新res #2 层序遍历:在进入新一层的循环时,首先将首结点的位置保存出来当作最左位置,然后对于遍历到的结点,都更新右结点的位置,遍历一层的结点后来计算宽度更新结果res

[LeetCode#687] Longest Univalue Path 最长相同值路径 Given a binary tree, find the length of the longest path where each node in the path has the same value. This path may or may not pass through the root. Note: The length of path between two nodes is represented by the number of edges between them. Example 1: Input: 5 / \ 4 5 / \ \ 1 1 5 Output: 2 Example 2: Input: 1 / \ 4 5 / \ \ 4 4 5 Output: 2 Note: The given binary tree has not more than 10000 nodes. The height of the tree is not more than 1000.

递归 当前结点和其左右子结点之间的关系了,如果其左子结点存在且和当前节点值相同,则left自增1,否则left重置0;同理,如果其右子结点存在且和当前节点值相同,则right自增1,否则right重置0。然后用left+right来更新结果res。 向上返回为max(left, right)


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

Chapter 9: Pathways that Harvest Chemical Energy

View Set

Leccion 3 self check Autoevaluation

View Set

Types of movements (that occurs at synovial joints)

View Set

E-Commerce Lecture 5 Online Business Models

View Set

Introduction to Computer Programming (Exam 1)

View Set