leetcode 学习心得 (3)

源代码地址:https://github.com/hopebo/hopelee

语言:C++

517. Super Washing Machines

You have n super washing machines on a line. Initially, each washing machine has some dresses or is empty.

For each move, you could choose any m (1 ≤ m ≤ n) washing machines, and pass one dress of each washing machine to one of its adjacent washing machines at the same time .

Given an integer array representing the number of dresses in each washing machine from left to right on the line, you should find the minimum number of moves to make all the washing machines have the same number of dresses. If it is not possible to do it, return -1.

Example1

Input: [1,0,5]

Output: 3

Explanation: 
1st move:    1     0 <-- 5    =>    1     1     4
2nd move:    1 <-- 1 <-- 4    =>    2     1     3    
3rd move:    2     1 <-- 3    =>    2     2     2   

Example2

Input: [0,3,0]

Output: 2

Explanation: 
1st move:    0 <-- 3     0    =>    1     2     0    
2nd move:    1     2 --> 0    =>    1     1     1     

Example3

Input: [0,2,0]

Output: -1

Explanation: 
It's impossible to make all the three washing machines have the same number of dresses. 

Note:

  1. The range of n is [1, 10000].
  2. The range of dresses number in a super washing machine is [0, 1e5].
解题思路:
  1. 首先将所有的衣服数相加得到总和sum,如果sum对n取余不为0,说明不能均分,返回-1。反之计算 ave = sum / n,为每台洗衣机容纳衣服的平均值。从前往后遍历洗衣机,利用当前的洗衣机位置将整体划分为两个部分来考虑。如果前面的整体(包含当前洗衣机)的需求量sum - i*ave为正,那么说明至少从前面部分往后移动 sum - i*ave 件衣服;如果该值为负,说明前面部分的衣服不够,至少从后面移动 i*ave - sum 件衣服,所以取其绝对值。针对每台洗衣机考虑,其至少移动 衣服初始数量-ave 件衣服。将两者取max,对每台洗衣机位置进行循环即可得到最终返回值。
刷题记录:
  1. 思路很奇妙,NO BUG FREE
518. Coin Change 2

You are given coins of different denominations and a total amount of money. Write a function to compute the number of combinations that make up that amount. You may assume that you have infinite number of each kind of coin.

Note: You can assume that

  • 0 <= amount <= 5000
  • 1 <= coin <= 5000
  • the number of coins is less than 500
  • the answer is guaranteed to fit into signed 32-bit integer

Example 1:

Input: amount = 5, coins = [1, 2, 5]
Output: 4
Explanation: there are four ways to make up the amount:
5=5
5=2+2+1
5=2+1+1+1
5=1+1+1+1+1

Example 2:

Input: amount = 3, coins = [2]
Output: 0
Explanation: the amount of 3 cannot be made up just with coins of 2.

Example 3:

Input: amount = 10, coins = [10] 
Output: 1

解题思路:

  1. 此题的关键在于dp算法不能重复计算相同的coin组成(只是加入的顺序不同),因此不能对确定的金额对内层的不用硬币做循环。只能将硬币加入的种类做外层循环,然后内层循环为不同的金额,计算加入不限个数的当前硬币,可以组合而成的不同金额数。这样每种方式下使用不同种类的硬币的个数是确定的。循环完成后,返回dp[amount]即可。
  2. 另外此题显然用递归也可以做,因为同一硬币可以使用多次,那么内层递归函数硬币的起始遍历位置与当前层相同。
520. Detect Capital

Given a word, you need to judge whether the usage of capitals in it is right or not.

We define the usage of capitals in a word to be right when one of the following cases holds:

  1. All letters in this word are capitals, like "USA".
  2. All letters in this word are not capitals, like "leetcode".
  3. Only the first letter in this word is capital if it has more than one letter, like "Google".
Otherwise, we define that this word doesn't use capitals in a right way.

Example 1:

Input: "USA"
Output: True

Example 2:

Input: "FlaG"
Output: False

Note: The input will be a non-empty word consisting of uppercase and lowercase latin letters.

解题思路:

  1. 统计字符串word中出现的大写字母的个数,然后根据题设的三个条件,对大写字母的个数进行判断,返回是否。
521. Longest Uncommon Subsequence I

Given a group of two strings, you need to find the longest uncommon subsequence of this group of two strings. The longest uncommon subsequence is defined as the longest subsequence of one of these strings and this subsequence should not be anysubsequence of the other strings.

A subsequence is a sequence that can be derived from one sequence by deleting some characters without changing the order of the remaining elements. Trivially, any string is a subsequence of itself and an empty string is a subsequence of any string.

The input will be two strings, and the output needs to be the length of the longest uncommon subsequence. If the longest uncommon subsequence doesn't exist, return -1.

Example 1:

Input: "aba", "cdc"
Output: 3
Explanation: The longest uncommon subsequence is "aba" (or "cdc"), 
because "aba" is a subsequence of "aba",
but not a subsequence of any other strings in the group of two strings.

Note:

  1. Both strings' lengths will not exceed 100.
  2. Only letters from a ~ z will appear in input strings.

解题思路:

  1. 如果给定的两个字符串相等,那么不存在uncommon subsequence,返回-1。否则返回两个字符串中较长的字符串的长度即可,因为较长的字符串的全部肯定是无法被短字符串以子串的方式得到的。
522. Longest Uncommon Subsequence II

Given a list of strings, you need to find the longest uncommon subsequence among them. The longest uncommon subsequence is defined as the longest subsequence of one of these strings and this subsequence should not be any subsequence of the other strings.

A subsequence is a sequence that can be derived from one sequence by deleting some characters without changing the order of the remaining elements. Trivially, any string is a subsequence of itself and an empty string is a subsequence of any string.

The input will be a list of strings, and the output needs to be the length of the longest uncommon subsequence. If the longest uncommon subsequence doesn't exist, return -1.

Example 1:

Input: "aba", "cdc", "eae"
Output: 3

Note:

  1. All the given strings' lengths will not exceed 10.
  2. The length of the given list will be in the range of [2, 50].
解题思路:
  1. 这个题的方法很多,自己的方法是将参数字符串向量按照字符串长度从大到小进行排序,优先探讨较长的字符串。定义一个map<string, int>来存储当前长度的字符串和其对应的数量,set<string>存储需要去进行比较的比当前字符串长的字符串集合,因为当前字符串可能是它们的子串。为什么要定义一个集合,而不是直接讨论当前字符串是否为所有比它长的字符串的子串,因为在前面的讨论中有些短的字符串就是更长的字符串的子串了,所以再和这些短的字符串比较是一种多余,只需要跟最长的字符串讨论即可,另外如果当前字符串不是任何比它长的串的子串,但是它在map中显示出现的数量不为1,也需要将其加入到集合中。
  2. 答案的方法有很多:1. 求出所有字符串的所有字符串,存入map中,选择出现次数为1的长度最长的字符串长度输出。2. 只是定义一个set<string>用单独的函数找出所有出现过重复的字符串,然后简单的进行二层循环,将当前串与所有比它长的串比较。
  3. 相信自己的思路,答案基本上都用了map或者set结构。
523. Continuous Subarray Sum

Given a list of non-negative numbers and a target integer k, write a function to check if the array has a continuous subarray of size at least 2 that sums up to the multiple of k, that is, sums up to n*k where n is also an integer.

Example 1:

Input: [23, 2, 4, 6, 7],  k=6
Output: True
Explanation: Because [2, 4] is a continuous subarray of size 2 and sums up to 6.

Example 2:

Input: [23, 2, 6, 4, 7],  k=6
Output: True
Explanation: Because [23, 2, 6, 4, 7] is an continuous subarray of size 5 and sums up to 42.

Note:

  1. The length of the array won't exceed 10,000.
  2. You may assume the sum of all the numbers is in the range of a signed 32-bit integer.

解题思路:

  1. 用set<int>结构存储前面连续子串和对k的余数,对于当前的curSum而言,只要它能把对k取余的结果减掉,那么对应的子串的和一定是k的整数倍的,所以只需要找前面的set中是否包含这个余数即可,如果不包含,则把当前余数加入到set结构中。
  2. 注意因为子串的长度至少为2,所以利用小技巧,将前一个求和结果在此求和讨论完之后再加入set中,可以省去子串长度的探讨。如果k为0的话,需要的余数就是curSum本身。
刷题记录:
  1. NO BUG FREE。要注意思路的转换,灵活运用之前学过的方法。

524. Longest Word in Dictionary through Deleting

Given a string and a string dictionary, find the longest string in the dictionary that can be formed by deleting some characters of the given string. If there are more than one possible results, return the longest word with the smallest lexicographical order. If there is no possible result, return the empty string.

Example 1:

Input:
s = "abpcplea", d = ["ale","apple","monkey","plea"]

Output: 
"apple"

Example 2:

Input:
s = "abpcplea", d = ["a","b","c"]

Output: 
"a"

Note:

  1. All the strings in the input will only contain lower-case letters.
  2. The size of the dictionary won't exceed 1,000.
  3. The length of all the strings in the input won't exceed 1,000. 
解题思路:
  1. 采用直接遍历的方法,对给定向量中的每个字符串判断是否为s的子串,如果是,那么比较其和返回字符串res的长度,如果大于res的长度,或者长度相同,ASCII码较小,那么将res改写为当前字符串。
525. Contiguous Array

Given a binary array, find the maximum length of a contiguous subarray with equal number of 0 and 1.

Example 1:

Input: [0,1]
Output: 2
Explanation: [0, 1] is the longest contiguous subarray with equal number of 0 and 1.

Example 2:

Input: [0,1,0]
Output: 2
Explanation: [0, 1] (or [1, 0]) is a longest contiguous subarray with equal number of 0 and 1.

Note: The length of the given binary array will not exceed 50,000.

解题思路:
  1. 本题要求最长的0与1数目相等的子字符串,那么定义一个整型变量prepond存储0~位置i 0比1多的个数,如果前面也出现过与prepond相等的位置,那么从那个位置到i的子串就是满足条件的连续子数组,取其最大值。注意在map<int, int> 存储多的个数与位置时,在开始加上location[0] = -1,方便第一次出现prepond为0的位置时,就可以将当前的数组长度算作是满足条件的一个选择。如果出现同样的prepond,不要用后面的位置去更新前面的位置,因为位置越前,可能后面计算得到的长度越大。
526. Beautiful Arrangement

Suppose you have N integers from 1 to N. We define a beautiful arrangement as an array that is constructed by these N numbers successfully if one of the following is true for the ith position (1 ≤ i ≤ N) in this array:

  1. The number at the ith position is divisible by i.
  2. i is divisible by the number at the ith position.

Now given N, how many beautiful arrangements can you construct?

Example 1:

Input: 2
Output: 2
Explanation: 

The first beautiful arrangement is [1, 2]:
Number at the 1st position (i=1) is 1, and 1 is divisible by i (i=1).
Number at the 2nd position (i=2) is 2, and 2 is divisible by i (i=2).
The second beautiful arrangement is [2, 1]:
Number at the 1st position (i=1) is 2, and 2 is divisible by i (i=1).
Number at the 2nd position (i=2) is 1, and i (i=2) is divisible by 1.

Note:

  1. N is a positive integer and will not exceed 15.

 解题思路:

  1. 用深度优先查找的方式进行递归调用,依次将1~N的每一个数循环放置在不同的合适位置上进行递归调用,记录所有可能的安排方式。
529. Minesweeper

Let's play the minesweeper game (Wikipediaonline game)!

You are given a 2D char matrix representing the game board. 'M' represents an unrevealed mine, 'E' represents an unrevealed empty square, 'B' represents a revealed blank square that has no adjacent (above, below, left, right, and all 4 diagonals) mines, digit ('1' to '8') represents how many mines are adjacent to this revealed square, and finally 'X' represents a revealed mine.

Now given the next click position (row and column indices) among all the unrevealed squares ('M' or 'E'), return the board after revealing this position according to the following rules:

  1. If a mine ('M') is revealed, then the game is over - change it to 'X'.
  2. If an empty square ('E') with no adjacent mines is revealed, then change it to revealed blank ('B') and all of its adjacent unrevealed squares should be revealed recursively.
  3. If an empty square ('E') with at least one adjacent mine is revealed, then change it to a digit ('1' to '8') representing the number of adjacent mines.
  4. Return the board when no more squares will be revealed.

Example 1:

Input: 

[['E', 'E', 'E', 'E', 'E'],
 ['E', 'E', 'M', 'E', 'E'],
 ['E', 'E', 'E', 'E', 'E'],
 ['E', 'E', 'E', 'E', 'E']]

Click : [3,0]

Output: 

[['B', '1', 'E', '1', 'B'],
 ['B', '1', 'M', '1', 'B'],
 ['B', '1', '1', '1', 'B'],
 ['B', 'B', 'B', 'B', 'B']]

Explanation:

Example 2:

Input: 

[['B', '1', 'E', '1', 'B'],
 ['B', '1', 'M', '1', 'B'],
 ['B', '1', '1', '1', 'B'],
 ['B', 'B', 'B', 'B', 'B']]

Click : [1,2]

Output: 

[['B', '1', 'E', '1', 'B'],
 ['B', '1', 'X', '1', 'B'],
 ['B', '1', '1', '1', 'B'],
 ['B', 'B', 'B', 'B', 'B']]

Explanation:

Note:

  1. The range of the input matrix's height and width is [1,50].
  2. The click position will only be an unrevealed square ('M' or 'E'), which also means the input board contains at least one clickable square.
  3. The input board won't be a stage when game is over (some mines have been revealed).
  4. For simplicity, not mentioned rules should be ignored in this problem. For example, you don't need to reveal all the unrevealed mines when the game is over, consider any cases that you will win the game or flag any squares.

 解题思路:

  1. 这个题就是依次对board中的点进行讨论,用深度优先遍历和广度优先遍历都可以。但是使用广度优先遍历时要注意一个问题是,在将待讨论的未揭晓的空区域('E'),加入队列以后,一定要将其值更改,避免在对队列中其旁边的点进行讨论时,会重复将这个点加入队列中,造成TLE。将该点改写为任何值都可以,因为在之后对该点进行讨论时会改写它为合适的正确值,数字或者'B'。
刷题记录:
  1. 思路没有问题,但是有点犹豫。然后写的时候慌里慌张,出现了一些编译错误的情况。记住一点:提高速度也不能慌,写错带来的时间成本更大。
530. Minimum Absolute Difference in BST

Given a binary search tree with non-negative values, find the minimum absolute difference between values of any two nodes.

Example:

Input:

   1
    
     3
    /
   2

Output:
1

Explanation:
The minimum absolute difference is 1, which is the difference between 2 and 1 (or between 2 and 3).

Note: There are at least two nodes in this BST.

解题思路:
  1. 这个题的技巧和之前的在二叉查找树中找重复次数最多的数一样,需要定义一个共有型整型变量来存储前一个比当前root的val值小的数,取当前根结点的val值与前一个数的差值的最小值为所求。其实就是对整棵树进行了中序遍历得到增序列,那么最小的绝对值之差一定是相邻元素之间的。
532. K-diff Pairs in an Array

Given an array of integers and an integer k, you need to find the number of unique k-diff pairs in the array. Here a k-diff pair is defined as an integer pair (i, j), where i and j are both numbers in the array and their absolute difference is k.

Example 1:

Input: [3, 1, 4, 1, 5], k = 2
Output: 2
Explanation: There are two 2-diff pairs in the array, (1, 3) and (3, 5).
Although we have two 1s in the input, we should only return the number of unique pairs.

Example 2:

Input:[1, 2, 3, 4, 5], k = 1
Output: 4
Explanation: There are four 1-diff pairs in the array, (1, 2), (2, 3), (3, 4) and (4, 5).

Example 3:

Input: [1, 3, 1, 5, 4], k = 0
Output: 1
Explanation: There is one 0-diff pair in the array, (1, 1).

Note:

  1. The pairs (i, j) and (j, i) count as the same pair.
  2. The length of the array won't exceed 10,000.
  3. All the integers in the given input belong to the range: [-1e7, 1e7].
解题思路:
  1. 算法就是一个空间与时间的权衡。用hash存储所有数的信息,时间复杂度为O(n),空间复杂度为O(n)。针对每一个不同的数,都查找其减去k的值是否存在。k == 0和k != 0时要分开讨论。
  2. 对原序列进行排序,然后使用顺序遍历或者二分查找的方式也可以。时间复杂度为O(nlogn),空间复杂度为O(1)。
535. Encode and Decode TinyURL
Note: This is a companion problem to the System Design problem: Design TinyURL.

TinyURL is a URL shortening service where you enter a URL such as https://leetcode.com/problems/design-tinyurl and it returns a short URL such as http://tinyurl.com/4e9iAk.

Design the encode and decode methods for the TinyURL service. There is no restriction on how your encode/decode algorithm should work. You just need to ensure that a URL can be encoded to a tiny URL and the tiny URL can be decoded to the original URL.

解题思路:
  1. 虽然是自主设计长网址和短网址的映射转换方法,但是实际上的对应关系还是需要通过数据库来存储的。
537. Complex Number Multiplication

Given two strings representing two complex numbers.

You need to return a string representing their multiplication. Note i2 = -1 according to the definition.

Example 1:

Input: "1+1i", "1+1i"
Output: "0+2i"
Explanation: (1 + i) * (1 + i) = 1 + i2 + 2 * i = 2i, and you need convert it to the form of 0+2i.

Example 2:

Input: "1+-1i", "1+-1i"
Output: "0+-2i"
Explanation: (1 - i) * (1 - i) = 1 + i2 - 2 * i = -2i, and you need convert it to the form of 0+-2i.

Note:

  1. The input strings will not have extra blank.
  2. The input strings will be given in the form of a+bi, where the integer a and b will both belong to the range of [-100, 100]. And the output should be also in this form.

解题思路:

  1. 用字符串的find_first_of函数和子串函数分别得到两个复数的实部和虚部。然后对其进行计算,得到结果的实部和虚部后转换成字符串返回。
538. Convert BST to Greater Tree

Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST.

Example:

Input: The root of a Binary Search Tree like this:
              5
            /   
           2     13

Output: The root of a Greater Tree like this:
             18
            /   
          20     13 
解题思路:
  1. 将二分查找树,比当前节点大的所有节点的值加到当前结点上,所以要进行反向的中序遍历,得到从大到小排列的序列,定义一个整型变量用来存储前面所有元素的和,然后加到当前节点上,再将左子结点作为参数递归调用函数。
539. Minimum Time Difference

Given a list of 24-hour clock time points in "Hour:Minutes" format, find the minimum minutes difference between any two time points in the list.

Example 1:

Input: ["23:59","00:00"]
Output: 1

Note:

  1. The number of time points in the given list is at least 2 and won't exceed 20000.
  2. The input time is legal and ranges from 00:00 to 23:59.
解题思路:
  1. 用快速排序将字符串向量按照字典编纂的顺序排序,自动为时间的从大到小排序,求相邻两个时间点的最小间隔即可。
  2. 使用桶排序,24*60,一共只有这些时间点,定义一个如此大小的bool向量用来表示这个时间点在向量中是否存在。然后求相邻为true的时间点的最小距离。
540. Single Element in a Sorted Array

Given a sorted array consisting of only integers where every element appears twice except for one element which appears once. Find this single element that appears only once.

Example 1:

Input: [1,1,2,3,3,4,4,8,8]
Output: 2

Example 2:

Input: [3,3,7,7,10,11,11]
Output: 10

Note: Your solution should run in O(log n) time and O(1) space.

解题思路:
  1. 同样类型的问题,在一个向量中只有一个数出现了一次,其他数出现了两次,找出这个数的问题。如果数组为无序的,那么对原数组的所有元素异或,即可得所求,时间复杂度为O(n);如果数组为有序的话,用二分法对数组进行遍历即可,时间复杂度为O(logn),可以直接通过比较nums[i]和nums[i^1]是否相等来决定下一次二分查找的范围。
541. Reverse String II
Given a string and an integer k, you need to reverse the first k characters for every 2k characters counting from the start of the string. If there are less than k characters left, reverse all of them. If there are less than 2k but greater than or equal to k characters, then reverse the first k characters and left the other as original.

Example:

Input: s = "abcdefg", k = 2
Output: "bacdfeg"
Restrictions:
  1. The string consists of lower English letters only.
  2. Length of the given string and k will in the range [1, 10000]

解题思路:

  1. 确定每次反转的子字符串的范围,起始位置和终止位置,起始位置以2k为大小增加,终止位置为起始位置+k和字符串最后一个字符位置的较小值。然后对确定范围内的字符串进行反转。
542. 01 Matrix

Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell.

The distance between two adjacent cells is 1.

Example 1: 
Input:

0 0 0
0 1 0
0 0 0
Output:
0 0 0
0 1 0
0 0 0

Example 2: 
Input:

0 0 0
0 1 0
1 1 1
Output:
0 0 0
0 1 0
1 2 1

Note:

  1. The number of elements of the given matrix will not exceed 10,000.
  2. There are at least one 0 in the given matrix.
  3. The cells are adjacent in only four directions: up, down, left and right.

解题思路:

  1. 用动态规划的方法,分别从 top left 和 down right 两个方向遍历数组,从左上遍历时,当前位置上方的点和左边的点已经计算出来它们各自从左上方向所能到达0的最短路径,因此将当前点的路径改写为这两者的较小值;从右下遍历时,由于当前位置下方的点和右边的点已经计算完成,所以将当前点的路径长度取为当前值和下方、右方点的距离加1之间的最小值即可。能够这么做的原因在于,如果一个原来为1的点到某个0的点的路径是最短的,那么这两个点所确定的这个矩形中每个点一定都为1,所以通过这样的遍历,一定能找出到每个1最短的0点的距离。
  2. 第二种方法是广度优先遍历的方法,先将所有为1的点的距离改写为最大距离,并且将所有为0的点加入到队列中。然后循环出队,判断其四周的节点通过当前节点到0的距离是否比四周的节点到0的距离要短,如果短的话,将四周的结点距离改写,并将其加入队列中。因为这个结点的距离有更新变短,那么就有可能导致它周围的结点通过它到0的距离变短。
刷题记录:
  1. NO BUG FREE,刚开始始终纠结于用DFS的方法去做,但是这个题其实不适合这种方法,因为一个结点到0的最小距离是可以通过四周每一个点的,那么中间递归调用的结点得到的结果肯定是不包含调用它的结点的路径的,所以结果会是片面的。
543. Diameter of Binary Tree

Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a binary tree is the length of the longest path between any two nodes in a tree. This path may or may not pass through the root.

Example:
Given a binary tree 

          1
         / 
        2   3
       /      
      4   5    

Return 3, which is the length of the path [4,2,1,3] or [5,2,1,3].

Note: The length of path between two nodes is represented by the number of edges between them.

解题思路:

  1. 定义一个递归函数用来计算树的高度,在求对以当前根结点为转折点的路径的最长长度时,就递归调用函数求其左子树和右子树的高度,两者高度之和即为最长路径。这一步计算也是包含在递归函数之内的,返回树的高度,但是在函数内部对最长路径进行计算和更改。
546. Remove Boxes

Given several boxes with different colors represented by different positive numbers. 
You may experience several rounds to remove boxes until there is no box left. Each time you can choose some continuous boxes with the same color (composed of k boxes, k >= 1), remove them and get k*k points.
Find the maximum points you can get.

Example 1:
Input:

[1, 3, 2, 2, 2, 3, 4, 3, 1]
Output:
23
Explanation:
[1, 3, 2, 2, 2, 3, 4, 3, 1] 
----> [1, 3, 3, 4, 3, 1] (3*3=9 points) 
----> [1, 3, 3, 3, 1] (1*1=1 points) 
----> [1, 1] (3*3=9 points) 
----> [] (2*2=4 points)

Note: The number of boxes n would not exceed 100.

解题思路:

  1. 这个题运用的dp算法非常精妙。之所以直接递归的方式会出现TLE的问题,是因为中间出现了很多不必要的重复计算消耗了时间,因此我们要构造合适的结构将中间计算产生的结果记录下来,并且在之后的计算中用到,这就是dp算法。那么本题中如何构造合理的结构呢,我们分析,对于一个数组来说,用什么时候将最后一个元素以及它之前与之相同的元素remove来划分不同种情况。如果整个序列中与最后一个元素相同的元素全在最后连续排列,那么将这连续序列先去除和后去除是一样的效果。但是如果在之前出现了相同的元素,但是中间存在间隔,那么就会有另一种情况出现,就是先将该元素与最后之间的元素序列去除,让该元素与最后的序列连在一块再去除,需要递归讨论这种情况所能得到的最大点数,与之前的结果取最大讨论。
  2. 基于上述的思路,我们采用三维数组的方式存储所有的结果。dp数组的定义必须涵盖可能出现的所有情况,但是数组中会有很大部分空间用不上,因为下标不满足实际的问题需求。dp[i][j][k] 表示消除从i~j的所有点,并且j之后有k个与之相同的点的序列所能得到的最大点数。
刷题记录:
  1. NO BUG FREE。
  2. 这一题动态规划的思路十分奇妙,下面有一点和动态规划有关的启发:dp算法构造的数组的下标表示什么含义,维度是多少,循环方式都很有讲究。交换dp数组的下标以及循环方式可能就是另一种问题。
  3. 关于链表,在使用链表的迭代器时,一定要千万小心,只要链表发生变化(增删)那么之前的迭代器变量就都可能发生变化,变得无效(即使是在递归函数中修改链表也会)。
547. Friend Circles

There are N students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a direct friend of B, and B is a direct friend of C, then A is an indirect friend of C. And we defined a friend circle is a group of students who are direct or indirect friends.

Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] = 1, then the ith and jth students are direct friends with each other, otherwise not. And you have to output the total number of friend circles among all the students.

Example 1:

Input: 
[[1,1,0],
 [1,1,0],
 [0,0,1]]
Output: 2
Explanation:The 0th and 1st students are direct friends, so they are in a friend circle. 
The 2nd student himself is in a friend circle. So return 2.

Example 2:

Input: 
[[1,1,0],
 [1,1,1],
 [0,1,1]]
Output: 1
Explanation:The 0th and 1st students are direct friends, the 1st and 2nd students are direct friends, 
so the 0th and 2nd students are indirect friends. All of them are in the same friend circle, so return 1.

Note:

  1. N is in range [1,200].
  2. M[i][i] = 1 for all students.
  3. If M[i][j] = 1, then M[j][i] = 1.
解题思路:
  1. 此题是一个利用DFS或BFS搜索的问题,定义一个bool型的向量来记录每个人是否已经被统计在某一朋友圈中 ,遍历每个人,如果当前人没有被统计在任一朋友圈中,那么将其作为新建的朋友圈,然后去深度或广度搜索其朋友,将其都加入到当前朋友圈中。找到不同的朋友圈个数即可。
  2. 注意队列的构造函数没有 queue<int> (1, 2) 这种结构。
551. Student Attendance Record I

You are given a string representing an attendance record for a student. The record only contains the following three characters:

  1. 'A' : Absent.
  2. 'L' : Late.
  3. 'P' : Present.

A student could be rewarded if his attendance record doesn't contain more than one 'A' (absent) or more than two continuous 'L' (late).

You need to return whether the student could be rewarded according to his attendance record.

Example 1:

Input: "PPALLP"
Output: True

Example 2:

Input: "PPALLL"
Output: False
解题思路:
  1. 定义大小为2的整型数组分别记录'A'出现的次数和'L'连续出现的次数。如果当前为'A',那么count[0]++;如果当前为'L',那么count[1]++,反之count[1]清0。如果某一次字符统计后 count[0] > 1 或者 count[1] > 2 ,返回 false。否则返回true。
552. Student Attendance Record II

Given a positive integer n, return the number of all possible attendance records with length n, which will be regarded as rewardable. The answer may be very large, return it after mod 109 + 7.

A student attendance record is a string that only contains the following three characters:

  1. 'A' : Absent.
  2. 'L' : Late.
  3. 'P' : Present.

A record is regarded as rewardable if it doesn't contain more than one 'A' (absent) or more than two continuous 'L' (late).

Example 1:

Input: n = 2
Output: 8 
Explanation:
There are 8 records with length 2 will be regarded as rewardable:
"PP" , "AP", "PA", "LP", "PL", "AL", "LA", "LL"
Only "AA" won't be regarded as rewardable owing to more than one absent times. 

Note: The value of n won't exceed 100,000.

解题思路:

  1. 这个题主要是要构造在每一次长度增加前后,符合条件的字符串数量的关系。用 count[i][j] 来表示 'A' 的数量小于等于i,末尾连续 'L' 的数量小于等于j的数量。在序列增加的过程中用末尾加 'P' , 'L' , 'A' 来分类讨论,方便计算数量间的关系。注意在构造动态关系式的时候一定要用前面的计算得出的变量来构造当前的变量,不要用前面的变量结合当前循环已经变更过的数量来做,会导致思路很混乱。
刷题记录:
  1. NO BUG FREE. 这个题相比之前的动态规划题,动态关系式更为复杂,所以需要严格细心的去构造。
553. Optimal Division

Given a list of positive integers, the adjacent integers will perform the float division. For example, [2,3,4] -> 2 / 3 / 4.

However, you can add any number of parenthesis at any position to change the priority of operations. You should find out how to add parenthesis to get the maximum result, and return the corresponding expression in string format. Your expression should NOT contain redundant parenthesis.

Example:

Input: [1000,100,10,2]
Output: "1000/(100/10/2)"
Explanation:
1000/(100/10/2) = 1000/((100/10)/2) = 200
However, the bold parenthesis in "1000/((100/10)/2)" are redundant, 
since they don't influence the operation priority. So you should return "1000/(100/10/2)". Other cases: 1000/(100/10)/2 = 50 1000/(100/(10/2)) = 50 1000/100/10/2 = 0.5 1000/100/(10/2) = 2

Note:

  1. The length of the input array is [1, 10].
  2. Elements in the given array will be in range [2, 1000].
  3. There is only one optimal division for each test case.

解题思路:

  1. 此题是通过括号来改变连续除法的结果,由于除法的特殊性,由除号构成的计算式最终都能转换成被除数的相乘除以除数的相乘,总的来说就是最大化被除数,最小化除数。对于这个题目来说,需要观察到无论怎样第一个数始终是作为被除数的,第二个数始终是除数,而且由于所有的元素都是正整数,所以将后面所有元素都能转换到被除数上的结果一定是最大值。因此当元素个数大于2时,将后面除法式用括号括起来即可。
554. Brick Wall

There is a brick wall in front of you. The wall is rectangular and has several rows of bricks. The bricks have the same height but different width. You want to draw a vertical line from the top to the bottom and cross the least bricks.

The brick wall is represented by a list of rows. Each row is a list of integers representing the width of each brick in this row from left to right.

If your line go through the edge of a brick, then the brick is not considered as crossed. You need to find out how to draw the line to cross the least bricks and return the number of crossed bricks.

You cannot draw a line just along one of the two vertical edges of the wall, in which case the line will obviously cross no bricks.

Example:

Input: 
[[1,2,2,1],
 [3,1,2],
 [1,3,2],
 [2,4],
 [3,1,2],
 [1,3,1,1]]
Output: 2
Explanation: 

Note:

  1. The width sum of bricks in different rows are the same and won't exceed INT_MAX.
  2. The number of bricks in each row is in range [1,10,000]. The height of wall is in range [1,10,000]. Total number of bricks of the wall won't exceed 20,000.
解题思路:
  1. 定义一个map<int, int>结构来存储在key的位置上出现间隙的砖块个数,选取其最大值,那么在其对应的间隙穿过墙壁所需穿过的砖块个数最少。
556. Next Greater Element III

Given a positive 32-bit integer n, you need to find the smallest 32-bit integer which has exactly the same digits existing in the integer nand is greater in value than n. If no such positive 32-bit integer exists, you need to return -1.

Example 1:

Input: 12
Output: 21

Example 2:

Input: 21
Output: -1

解题思路:

  1. 类似与之间做的一题,从低位往高位遍历,直到找到小于最大值的那个数,如果是递增序列,那么不存在通过转换更大的数。否则将找到的位置上的数与前边序列刚好大于它的数相交换,然后将后面位置的数反向(从小到大)加到数值的尾部即可。这个题如果一开始将数转换为字符串来做,可以更直接的访问每个位置上的数,不用通过除10取余的方式,也不用定义向量来存储之前位置上的数。
  2. 注意转换之后要观察结果是否在32bit 有符号整型数的表示范围内,否则返回-1。
557. Reverse Words in a String III

Given a string, you need to reverse the order of characters in each word within a sentence while still preserving whitespace and initial word order.

Example 1:

Input: "Let's take LeetCode contest"
Output: "s'teL ekat edoCteeL tsetnoc"

Note: In the string, each word is separated by single space and there will not be any extra space in the string.

解题思路:

  1. 用参数字符串来初始化字符串输入流 stringstream ,然后依次读入单词,将其反转后加到返回字符串的尾部。
560. Subarray Sum Equals K

Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k.

Example 1:

Input:nums = [1,1,1], k = 2
Output: 2

Note:

  1. The length of the array is in range [1, 20,000].
  2. The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7]. 
解题思路:
  1. 用map结构存储前面序列的和以及其对应出现的次数,当前元素和为sum时,如果preSum[sum-k]存在,那么将其个数加到返回结果中。
561. Array Partition I

Given an array of 2n integers, your task is to group these integers into n pairs of integer, say (a1, b1), (a2, b2), ..., (an, bn) which makes sum of min(ai, bi) for all i from 1 to n as large as possible.

Example 1:

Input: [1,4,3,2]

Output: 4
Explanation: n is 2, and the maximum sum of pairs is 4 = min(1, 2) + min(3, 4).

Note:

  1. n is a positive integer, which is in the range of [1, 10000].
  2. All the integers in the array will be in the range of [-10000, 10000].

解题思路:

  1. 将原数组重排后,每隔1个元素输出一个。
563. Binary Tree Tilt

Given a binary tree, return the tilt of the whole tree.

The tilt of a tree node is defined as the absolute difference between the sum of all left subtree node values and the sum of all right subtree node values. Null node has tilt 0.

The tilt of the whole tree is defined as the sum of all nodes' tilt.

Example:

Input: 
         1
       /   
      2     3
Output: 1
Explanation: 
Tilt of node 2 : 0
Tilt of node 3 : 0
Tilt of node 1 : |2-3| = 1
Tilt of binary tree : 0 + 0 + 1 = 1

Note:

  1. The sum of node values in any subtree won't exceed the range of 32-bit integer.
  2. All the tilt values won't exceed the range of 32-bit integer.
解题思路:
  1. 此题是一个递归调用问题,要想求当前节点的 tilt ,首先必须知道其左子树和右子树的和,因此用递归函数调用其左子结点和右子结点返回其子树的和,然后在当前函数中计算左子树和右子树和的差的绝对值,作为当前结点的silt,加到返回变量中。然后返回包含根结点在内的结点和。
564. Find the Closest Palindrome

Given an integer n, find the closest integer (not including itself), which is a palindrome.

The 'closest' is defined as absolute difference minimized between two integers.

Example 1:

Input: "123"
Output: "121"

Note:

  1. The input n is a positive integer represented by string, whose length will not exceed 18.
  2. If there is a tie, return the smaller one as answer.

解题思路:

  1. 此题思路挺简单的,就是从大于原数的方向和小于原数的方向去找最接近的回文数。首先直接将原数对半分,然后将后半部分改写为与前半部分相对称的形式,组成回文字符串。如果得到的回文数大于原数,那么只需要找比其小的;如果小于原数,只需要再找比原数大的,再比较其绝对值差;如果相等,那么既要找大的也要找小的。
  2. 在找更大或者更小的数的过程中,由于前半部分决定了构造的回文字符串数的大小。所以直接在前半部分的数上加1或减1即可。但是在减1时存在特殊情况,就是如果前面是10000的话,减一后长度减少,可能导致后缀的字符串的第一位进入前半部分。所以在这种情况下,直接将全部位置上的字符置'9'即可。
刷题记录:
  1. NO BUG FREE
565. Array Nesting

A zero-indexed array A consisting of N different integers is given. The array contains all integers in the range [0, N - 1].

Sets S[K] for 0 <= K < N are defined as follows:

S[K] = { A[K], A[A[K]], A[A[A[K]]], ... }.

Sets S[K] are finite for each K and should NOT contain duplicates.

Write a function that given an array A consisting of N integers, return the size of the largest set S[K] for this array.

Example 1:

Input: A = [5,4,0,3,1,6,2]
Output: 4
Explanation: 
A[0] = 5, A[1] = 4, A[2] = 0, A[3] = 3, A[4] = 1, A[5] = 6, A[6] = 2.
One of the longest S[K]: S[0] = {A[0], A[5], A[6], A[2]} = {5, 6, 2, 0}

Note:

  1. N is an integer within the range [1, 20,000].
  2. The elements of A are all distinct.
  3. Each element of array A is an integer within the range [0, N-1].
解题思路:
  1. 从前往后遍历数组,依次找到元素组成的循环圈,如果一个元素已经包含在之前找到的集合内,那么对其做标记,可以将其位置上的元素值改为-1,也可以定义一个bool向量来单独存储。每次找到一个完整的集合后,取其最大值,然后将集合清空。
566. Reshape the Matrix

In MATLAB, there is a very useful function called 'reshape', which can reshape a matrix into a new one with different size but keep its original data.

You're given a matrix represented by a two-dimensional array, and two positive integers r and c representing the row number and column number of the wanted reshaped matrix, respectively.

The reshaped matrix need to be filled with all the elements of the original matrix in the same row-traversing order as they were.

If the 'reshape' operation with given parameters is possible and legal, output the new reshaped matrix; Otherwise, output the original matrix.

Example 1:

Input: 
nums = 
[[1,2],
 [3,4]]
r = 1, c = 4
Output: 
[[1,2,3,4]]
Explanation:
The row-traversing of nums is [1,2,3,4]. The new reshaped matrix is a 1 * 4 matrix, fill it row by row by using the previous list.

Example 2:

Input: 
nums = 
[[1,2],
 [3,4]]
r = 2, c = 4
Output: 
[[1,2],
 [3,4]]
Explanation:
There is no way to reshape a 2 * 2 matrix to a 2 * 4 matrix. So output the original matrix.

Note:

  1. The height and width of the given matrix is in range [1, 100].
  2. The given r and c are all positive.
解题思路:
  1. 二层循环对原数组进行遍历,定义整型变量row和col用来表示当前数该存入转换后的矩阵中的位置,每次存入后将col++,如果自增后的col等于转换后矩阵的列数,此时将row++,col重置为0。继续循环。
567. Permutation in String

Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. In other words, one of the first string's permutations is the substring of the second string.

Example 1:

Input:s1 = "ab" s2 = "eidbaooo"
Output:True
Explanation: s2 contains one permutation of s1 ("ba").

Example 2:

Input:s1= "ab" s2 = "eidboaoo"
Output: False

Note:

  1. The input strings only contain lower case letters.
  2. The length of both given strings is in range [1, 10,000].
解题思路:
  1. 此题和之前的题目思路一致,由于包含模式串s1的任意排列都可以,所以只需要目标串s2的某个子串与s1的长度相同,且包含s1的所有字符。用一个大小为26的数组来存储s1中每个字符的个数,然后遍历s2字符串,如果对应位置i的字符数量大于0,那么将其包含进来是有意思的,将count--(这里的count指的是在长度为n的字符串中还需要的有效字符)。如果i-n >= 0,说明统计范围的长度超出了s1的长度,将头部的字符移出去,如果头部字符对应的数量<0,那么说明子串中有多余的该字符,移出时count不做改变,但是如果其数量 >= 0,移出后就又多缺了一个该字符,将count++。如果某次循环时count刚好为0,说明长度为n的子串中所有字符都是有效的,即是s1的一个排列,返回true。
572. Subtree of Another Tree

Given two non-empty binary trees s and t, check whether tree t has exactly the same structure and node values with a subtree of s. A subtree of s is a tree consists of a node in s and all of this node's descendants. The tree s could also be considered as a subtree of itself.

Example 1:
Given tree s:

     3
    / 
   4   5
  / 
 1   2
Given tree t:
   4 
  / 
 1   2
Return true, because t has the same structure and node values with a subtree of s.

Example 2:
Given tree s:

     3
    / 
   4   5
  / 
 1   2
    /
   0
Given tree t:
   4
  / 
 1   2
Return false.

解题思路:

  1. 使用递归函数求解是最方便的,首先调用子函数比较从当前节点出发的子树与目标树是否相同,如果相同则返回true,否则递归调用判断从其左子结点出发的子树和右子结点出发的子树是否与目标树相同,如果存在相同,那么返回true,否则返回false。
  2. 定义比较两个子树是否相同的递归函数,首先比较根结点是否相同,如果相同那么递归调用其本身,比较根结点的左子结点和右子结点是否相同。
刷题记录:
  1. 最近总喜欢出compile error的错误,是不是写的时候不够认真,而且虽然给定的参数根结点是不为空的,但是递归调用时的根结点可能为null,也没见你处理。
575. Distribute Candies

Given an integer array with even length, where different numbers in this array represent different kinds of candies. Each number means one candy of the corresponding kind. You need to distribute these candies equally in number to brother and sister. Return the maximum number of kinds of candies the sister could gain.

Example 1:

Input: candies = [1,1,2,2,3,3]
Output: 3
Explanation:
There are three different kinds of candies (1, 2 and 3), and two candies for each kind.
Optimal distribution: The sister has candies [1,2,3] and the brother has candies [1,2,3], too. 
The sister has three different kinds of candies. 

Example 2:

Input: candies = [1,1,2,3]
Output: 2
Explanation: For example, the sister has candies [2,3] and the brother has candies [1,1]. 
The sister has two different kinds of candies, the brother has only one kind of candies. 

Note:

  1. The length of the given array is in range [2, 10,000], and will be even.
  2. The number in given array is in range [-100,000, 100,000].
解题思路:
  1. 通过快速排序或者借助hash集合计算出不同糖果的种类个数,然后返回种类个数与每个人所能分配到糖果个数的较小值即可。
  2. 注意 max 和 min 函数不接受类型为 unsigned int 的实际参数,所以不能在参数位置直接写 candies.size(),需要做强制类型转换。
576. Out of Boundary Paths

There is an m by n grid with a ball. Given the start coordinate (i,j) of the ball, you can move the ball to adjacent cell or cross the grid boundary in four directions (up, down, left, right). However, you can at most move N times. Find out the number of paths to move the ball out of grid boundary. The answer may be very large, return it after mod 109 + 7.

Example 1:

Input:m = 2, n = 2, N = 2, i = 0, j = 0
Output: 6
Explanation:

Example 2:

Input:m = 1, n = 3, N = 3, i = 0, j = 1
Output: 12
Explanation:

Note:

  1. Once you move the ball out of boundary, you cannot move it back.
  2. The length and height of the grid is in range [1,50].
  3. N is in range [0,50].

解题思路:

  1. 用DP算法来解决这个问题,分为正向和反向两种方法。正向的方法是从初识位置出发,循环计算经过每次移动后,到数组中不同位置的路径数。每次移动前,将四条边上的点的个数作为可以走出边界的方法数加入到返回变量中。然后用dp算法进行移动,每个位置上的不同路径数等于上下左右四个位置上的点数之和。可以进一步优化,在主函数内一次大循环搞定两个过程。
  2. 反向的dp算法更为奇妙,是从边界外往数组内的位置移动,每次移动时,当前位置上的路径个数等于上下左右的点的路径个数之和,如果上下左右的点有涉及到边界之外的,其路径值用1代替,相当于从边界外移动一步进来。最后用到起始点的路径数dp[i][j]作为返回值。
581. Shortest Unsorted Continuous Subarray

Given an integer array, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order, too.

You need to find the shortest such subarray and output its length.

Example 1:

Input: [2, 6, 4, 8, 10, 9, 15]
Output: 5
Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order.

Note:

  1. Then length of the input array is in range [1, 10,000].
  2. The input array may contain duplicates, so ascending order here means <=. 
解题思路:
  1. 从两个反向遍历数组,确定需要经过重新排序的左边界和右边界,从前往后遍历时,用一个变量maxNum记录前面序列的所有元素最大值,如果遍历过程中出现元素小于这个最大值,说明当前元素肯定是要和前面序列一块重排的,将end改写为当前元素的下标,一直到循环结束;从后往前遍历时同理,用一个整型变量minNum记录后面序列的最小值,如果当前元素是大于这个最小值的,那么当前元素肯定需要重排,将begin改写为当前元素的下标。最后确定的边界就是begin和end,返回end-begin+1为需要重排的数组子序列的长度。
583. Delete Operation for Two Strings

Given two words word1 and word2, find the minimum number of steps required to make word1 and word2 the same, where in each step you can delete one character in either string.

Example 1:

Input: "sea", "eat"
Output: 2
Explanation: You need one step to make "sea" to "ea" and another step to make "eat" to "ea".

Note:

  1. The length of given words won't exceed 500.
  2. Characters in given words can only be lower-case letters.
解题思路:
  1. 此题可以转换为求两个字符串的最长共有子串的问题,然后用字符串的长度减去共有子串的长度则为当前字符串需要删除的字符个数。求两个字符串的最长公共子串是一个处理过的问题,现在还不会处理很失望。用dp算法,二维数组的两个下标i, j分别表示两个字符串考虑进去的长度,数值为这两部分字符串共有子串的最大长度。如果word1[i-1] == word2[j-1],dp[i][j] = 1 + dp[i-1][j-1];反之,dp[i][j] = max(dp[i-1][j], dp[i][j-1])。
刷题记录:
  1. DP算法求两个字符串最长共有子串的长度的问题还不会!NO BUG FREE
587. Erect the Fence

There are some trees, where each tree is represented by (x,y) coordinate in a two-dimensional garden. Your job is to fence the entire garden using the minimum length of rope as it is expensive. The garden is well fenced only if all the trees are enclosed. Your task is to help find the coordinates of trees which are exactly located on the fence perimeter.

Example 1:

Input: [[1,1],[2,2],[2,0],[2,4],[3,3],[4,2]]
Output: [[1,1],[2,0],[4,2],[3,3],[2,4]]
Explanation:

Example 2:

Input: [[1,2],[2,2],[4,2]]
Output: [[1,2],[2,2],[4,2]]
Explanation:
Even you only have trees in a line, you need to use rope to enclose them. 

Note:

  1. All trees should be enclosed together. You cannot cut the rope to enclose trees that will separate them in more than one group.
  2. All input integers will range from 0 to 100.
  3. The garden has at least one tree.
  4. All coordinates are distinct.
  5. Input points have NO order. No order required for output.

解题思路:

  1. 此题的思路是从所有树中最左端的最下方树开始(因为最左端的树一定是在围住所有树的绳子路径上的),依次找能包围所有树的下一颗树,如何定义这个可以包围所有树呢,是指从当前树到下一颗树,再到剩下所有的树的路径是一个顺时针变化(右手定则),即从当前树到下一颗树的向量,与下一颗树到剩下的树的向量积为负(正负表示方向),即方向指向坐标轴里,与z轴正方向相反的方向。如果当前的向量积为正,那么把指定下一颗树的变量改写为循环的当前树。注意如果向量积为0,说明两个结点共线,取下一颗树为较远的那个结点,避免在下次遍历时重复的加入节点。在遍历结束,找到能包围所有树的下一结点后,将所有共线的结点加入到返回向量中,并定义bool型数组来指示当前结点是否已经被加入以避免重复。然后将下一结点赋给当前结点,从下一结点出发寻找下一个能包围所有树的结点。直到下一结点为初始结点时形成一个圈,结束循环。
刷题记录:
  1. 思路很奇妙,首先是利用了向量积在判断三个结点是顺时针转动还是逆时针的应用,其次使用了向量积向量形式的计算公式。
  2. 在临界和特殊值的处理上考虑不清,思维比较混乱,NO BUG FREE
591. Tag Validator

Given a string representing a code snippet, you need to implement a tag validator to parse the code and return whether it is valid. A code snippet is valid if all the following rules hold:

  1. The code must be wrapped in a valid closed tag. Otherwise, the code is invalid.
  2. A closed tag (not necessarily valid) has exactly the following format : <TAG_NAME>TAG_CONTENT</TAG_NAME>. Among them, <TAG_NAME> is the start tag, and </TAG_NAME> is the end tag. The TAG_NAME in start and end tags should be the same. A closed tag is valid if and only if the TAG_NAME and TAG_CONTENT are valid.
  3. A valid TAG_NAME only contain upper-case letters, and has length in range [1,9]. Otherwise, the TAG_NAME is invalid.
  4. A valid TAG_CONTENT may contain other valid closed tags, cdata and any characters (see note1) EXCEPT unmatched <, unmatched start and end tag, and unmatched or closed tags with invalid TAG_NAME. Otherwise, the TAG_CONTENT is invalid.
  5. A start tag is unmatched if no end tag exists with the same TAG_NAME, and vice versa. However, you also need to consider the issue of unbalanced when tags are nested.
  6. < is unmatched if you cannot find a subsequent >. And when you find a < or </, all the subsequent characters until the next > should be parsed as TAG_NAME (not necessarily valid).
  7. The cdata has the following format : <![CDATA[CDATA_CONTENT]]>. The range of CDATA_CONTENT is defined as the characters between <![CDATA[ and the first subsequent ]]>.
  8. CDATA_CONTENT may contain any characters. The function of cdata is to forbid the validator to parse CDATA_CONTENT, so even it has some characters that can be parsed as tag (no matter valid or invalid), you should treat it as regular characters.

Valid Code Examples:

Input: "<DIV>This is the first line <![CDATA[<div>]]></DIV>"
Output: True
Explanation:
The code is wrapped in a closed tag : <DIV> and </DIV>.
The TAG_NAME is valid, the TAG_CONTENT consists of some characters and cdata.
Although CDATA_CONTENT has unmatched start tag with invalid TAG_NAME, it should be considered as plain text, not parsed as tag.
So TAG_CONTENT is valid, and then the code is valid. Thus return true.
Input: "<DIV>>> ![cdata[]] <![CDATA[<div>]>]]>]]>>]</DIV>"
Output: True
Explanation:
We first separate the code into : start_tag|tag_content|end_tag.
start_tag -> "<DIV>"
end_tag -> "</DIV>"
tag_content could also be separated into : text1|cdata|text2.
text1 -> ">> ![cdata[]] "
cdata -> "<![CDATA[<div>]>]]>", where the CDATA_CONTENT is "<div>]>"
text2 -> "]]>>]"
The reason why start_tag is NOT "<DIV>>>" is because of the rule 6. The reason why cdata is NOT "<![CDATA[<div>]>]]>]]>" is because of the rule 7.

Invalid Code Examples:

Input: "<A>  <B> </A>   </B>"
Output: False
Explanation: Unbalanced. If "<A>" is closed, then "<B>" must be unmatched, and vice versa.

Input: "<DIV>  div tag is not closed  <DIV>"
Output: False

Input: "<DIV>  unmatched <  </DIV>"
Output: False

Input: "<DIV> closed tags with invalid tag name  <b>123</b> </DIV>"
Output: False

Input: "<DIV> unmatched tags with invalid tag name  </1234567890> and <CDATA[[]]>  </DIV>"
Output: False

Input: "<DIV>  unmatched start tag <B>  and unmatched end tag </C>  </DIV>"
Output: False

Note:

  1. For simplicity, you could assume the input code (including the any characters mentioned above) only contain lettersdigits'<','>','/','!','[',']' and ' '.

解题思路:

  1. 此题需要准确的捕捉到几个特定部分分割符(字符串),并且由于字符串之间存在包含和重叠的关系,所以优先查找复杂的字符串,再查找被包含的简单字符串。
  2. 首先从当前位置查找往后长度为9的开头字符串是否为 "<![CDATA[",如果为它,继续往后查找第一次出现 "]]>" 的位置,如果没查到,返回false,否则这期间的字符串可以为任意值。下一次查找从之后的第一个位置开始;如果开头不是上述字符串,如果开头是 "</" 那么继续往后查找 ">" 的位置,这其间的字符串即为 tag-name ,根据定义的规则判断该 tag-name 是否有效,即是否所有字符均为大写字符,而且长度在1~9之间,并且要和栈中存储的之前的(即栈顶)节开头的 tag-name 是否相同;如果开头也不是上述字符串,那么判断是否以 "<" 开头,如果是,查找下一个 ">" 的位置,这其中的字符串就是一个 tag-name 的开始,判断其是否符合规则后加入栈中。
  3. 然后在每次循环都需判断当前位置不为0时,栈是否为空,如果为空,说明错误;结束所有循环时,所有的 tag 应该都已出栈,判断栈是否为空。
  4. 利用整型变量可以存储 string.find_first_of(string ) 的结果,再进行是否等于 string::npos 的判断,来得出是否找到的结果。要注意如果参数是字符串的话,并不是查找整个字符串,而是查找出现字符串中任意字符的位置。如果需要查找特定字符串,使用find函数。
刷题记录:
  1. 此题需要找到关键的信息和标识。NO BUG FREE
592. Fraction Addition and Subtraction

Given a string representing an expression of fraction addition and subtraction, you need to return the calculation result in string format. The final result should be irreducible fraction. If your final result is an integer, say 2, you need to change it to the format of fraction that has denominator 1. So in this case, 2 should be converted to 2/1.

Example 1:

Input:"-1/2+1/2"
Output: "0/1"

Example 2:

Input:"-1/2+1/2+1/3"
Output: "1/3"

Example 3:

Input:"1/3-1/2"
Output: "-1/6"

Example 4:

Input:"5/3+1/3"
Output: "2/1"

Note:

  1. The input string only contains '0' to '9''/''+' and '-'. So does the output.
  2. Each fraction (input and output) has format ±numerator/denominator. If the first input fraction or the output is positive, then '+' will be omitted.
  3. The input only contains valid irreducible fractions, where the numerator and denominator of each fraction will always be in the range [1,10]. If the denominator is 1, it means this fraction is actually an integer in a fraction format defined above.
  4. The number of given fractions will be in the range [1,10].
  5. The numerator and denominator of the final result are guaranteed to be valid and in the range of 32-bit int.
解题思路:
  1. 这个题思路没问题,对分数进行加减运算,就是对其分母进行通分,然后将其分子相加减,最后计算得到的结果再进行用最大公因子约分。我的方法是对所有的分数都采取统一的公倍数,然后将所有的分子加起来,然后统一约分,答案的方法是每读入一个字符串表示的分数,就将其与前面的结果相计算后直接约分。
  2. 在读入数字和字符时,可以采用字符串输入流连续读入数字和符号,很方便。
593. Valid Square

Given the coordinates of four points in 2D space, return whether the four points could construct a square.

The coordinate (x,y) of a point is represented by an integer array with two integers.

Example:

Input: p1 = [0,0], p2 = [1,1], p3 = [1,0], p4 = [0,1]
Output: True

Note:

  1. All the input integers are in the range [-10000, 10000].
  2. A valid square has four equal sides with positive length and four equal angles (90-degree angles).
  3. Input points have no order.
解题思路:
  1. 这个题没有太多循环的操作,就是在于用什么样合适的方法来判断一个正方形的特性。我使用的方法是将原来的四个点按照横坐标从小到大,纵坐标从小到大排列后,计算可能的为四条边的长度,判断这四条边是否相等且不等于0,因此构成一个正四边形,如果再加上某个角为90°的条件就可以说明这是个正方形。
  2. 答案的方法普遍是计算6条边的长度,根据线段长度的性质来判断的,将6条边的长度存入集合中,最后的出现的长度应该只有2种,且不包含0,即为正方形。
594. Longest Harmonious Subsequence

We define a harmonious array is an array where the difference between its maximum value and its minimum value is exactly 1.

Now, given an integer array, you need to find the length of its longest harmonious subsequence among all its possible subsequences.

Example 1:

Input: [1,3,2,2,5,2,3,7]
Output: 5
Explanation: The longest harmonious subsequence is [3,2,2,2,3].

Note: The length of the input array will not exceed 20,000.

解题思路:
  1. 如果存在两个相邻的数(差值为1),那么在整个数组中,所有的这两个数都可以组成符合条件的子序列。因此我们要找的就是个数和最大的两个相邻整数。
  2. 用一个map<int, int>存储向量中出现的整数以及出现次数,用迭代器遍历map结构,先判断当前键值+1是否存在,如果存在,用当前的数量加上其数量的和与返回变量取较大值。
  3. 判断map结构中一个key是否存在时,一定只能用count函数,只要涉及到map[key] == 0的键值的访问,即使这个键值事先不存在,也会在执行这条语句时加入到map中,导致map中元素的无限循环。
598. Range Addition II

Given an m * n matrix M initialized with all 0's and several update operations.

Operations are represented by a 2D array, and each operation is represented by an array with two positive integers a and b, which means M[i][j] should be added by one for all 0 <= i < a and 0 <= j < b.

You need to count and return the number of maximum integers in the matrix after performing all the operations.

Example 1:

Input: 
m = 3, n = 3
operations = [[2,2],[3,3]]
Output: 4
Explanation: 
Initially, M = 
[[0, 0, 0],
 [0, 0, 0],
 [0, 0, 0]]

After performing [2,2], M = 
[[1, 1, 0],
 [1, 1, 0],
 [0, 0, 0]]

After performing [3,3], M = 
[[2, 2, 1],
 [2, 2, 1],
 [1, 1, 1]]

So the maximum integer in M is 2, and there are four of it in M. So return 4.

Note:

  1. The range of m and n is [1,40000].
  2. The range of a is [1,m], and the range of b is [1,n].
  3. The range of operations size won't exceed 10,000.
解题思路:
  1. 遍历参数向量,找到其中最小的a和最小的b,因为只有在最小的0~a-1和0~b-1范围内的数是每一次操作都有递增的,因此它们是最大的数。
599. Minimum Index Sum of Two Lists

Suppose Andy and Doris want to choose a restaurant for dinner, and they both have a list of favorite restaurants represented by strings.

You need to help them find out their common interest with the least list index sum. If there is a choice tie between answers, output all of them with no order requirement. You could assume there always exists an answer.

Example 1:

Input:
["Shogun", "Tapioca Express", "Burger King", "KFC"]
["Piatti", "The Grill at Torrey Pines", "Hungry Hunter Steakhouse", "Shogun"]
Output: ["Shogun"]
Explanation: The only restaurant they both like is "Shogun".

Example 2:

Input:
["Shogun", "Tapioca Express", "Burger King", "KFC"]
["KFC", "Shogun", "Burger King"]
Output: ["Shogun"]
Explanation: The restaurant they both like and have the least index sum is "Shogun" with index sum 1 (0+1).

Note:

  1. The length of both lists will be in the range of [1, 1000].
  2. The length of strings in both lists will be in the range of [1, 30].
  3. The index is starting from 0 to the list length minus 1.
  4. No duplicates in both lists.

解题思路:

  1. 由于要找出两个向量中公共的字符串,以及下标和最小的组合,因此时间复杂度至少为O(n+m)。用一个map<string, int>结构存储在第一个向量中出现过的字符串和其对应的下标,在遍历第二个向量时,判断在map结构中是否存在,如果存在,比较其下标和是否小于等于维护的最小下标和,如果等于,往返回向量中加入字符串;如果小于,清空原向量后再加入,并将最小下标和改写为当前的下标和。
600. Non-negative Integers without Consecutive Ones

Given a positive integer n, find the number of non-negative integers less than or equal to n, whose binary representations do NOT contain consecutive ones.

Example 1:

Input: 5
Output: 5
Explanation: 
Here are the non-negative integers <= 5 with their corresponding binary representations:
0 : 0
1 : 1
2 : 10
3 : 11
4 : 100
5 : 101
Among them, only integer 3 disobeys the rule (two consecutive ones) and the other 5 satisfy the rule. 

Note: 1 <= n <= 109

解题思路:

  1. 整体的思路是根据原数中出现'1'的位置来增加符合条件的数的数量,当某个位置出现'1'时,那么符合条件的数为当前位置置'0',从下一个位置起的00000~11111之间的所有不包含连续'1'的数都是符合条件的。同时还需判断前一位置是否为'1',如果前一位置也为'1',由于前一位置为'0'时所有符合条件的数已经算过了,那么其实此时增加的是前一位置置'1',当前位置置'0'时剩下位0000~1111任意符合条件的数。即使再往后存在某一位置为'1',前面原本为'1'的位置已经不可能全部置'1',因此存在连续'1',前面位置置'0'时讨论的情况已经涵盖后面所有的情况,因此此时直接返回统计结果。如果循环到最后都没有出现连续'1'而返回,最终的结果需要加上1,即原数本身。
  2. 如何求不同长度,00000~11111的符合条件(没有出现连续'1'的数)呢,用斐波那契数列序列的方法,假设count[i]为长度为1的符合条件的数,那么所有的count[i-1]加上'0'都是符合条件的数;如果第i位为'1'时,第i-1位其实就固定为'0',前i-2位任意,因此数量为count[i-2]。所有count[i] = count[i-1] + count[i-2]。
刷题记录:
  1. NO BUG FREE。
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:

  1. The input array won't violate no-adjacent-flowers rule.
  2. The input array size is in the range of [1, 20000].
  3. n is a non-negative integer which won't exceed the input array size.

解题思路:

  1. 遍历原向量中的位置,如果当前位置为0,且前后位置要么处于边界上,要么也为空,说明当前位置可植入新的植物,将n--,并且与0进行判断,如果减少到0,返回true。只要出现可以植入的位置就立即植入。
  2. 注意对边界情况进行讨论,就是一开始n为0的情况。
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. 答案中的方法更巧妙,直接使用的是原函数递归,在函数内先递归调用求左子树和右子树分别转换为串的字符串结果后,再根据结果的情况,来对字符串进行适当组合后返回。
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.txtf2.txt ... fn.txt with content f1_contentf2_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:

  1. No order is required for the final output.
  2. 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].
  3. The number of files given is in the range of [1,20000].
  4. You may assume no files or directories share the same name in the same directory.
  5. 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:
  1. Imagine you are given a real file system, how will you search files? DFS or BFS?
  2. If the file content is very large (GB level), how will you modify your solution?
  3. If you can only read the file by 1kb each time, how will you modify your solution?
  4. 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?
  5. How to make sure the duplicated files you find are not false positive?

解题思路:

  1. 使用hash表将不同文件内容对应的文件路径和文件名组合存储下来,完成对参数向量的遍历以后,再顺序遍历map结构,将同一个内容(key)下如果存在大于等于2的文件是用一个内容,将其加入到返回向量中即可。
  2. 对于拓展问题的解答,BFS搜索会耗费更多的空间,但是会搜素的更快,因为是直接在当前路径下继续进行的,省去了DFS迭代的耗时。如果文件内容过大,直接对内容hash显然是不成立的,可以先对文件大小hash,相同文件大小下在对加密序列hash(md5),最后才需要一个字节一个字节的比较。
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:

  1. The length of the given array won't exceed 1000.
  2. The integers in the given array are in the range of [0, 1000].

解题思路:

  1. 首先对原数组进行由小到大的重排,利用两条短边之和大于第三边即可以构成三角形的法则来进行遍历,时间复杂度为O(n^2)。外层循环确定最短边,内存循环依次对第二条边和第三条边进行,直到第三条边大于等于两小边之和时,将可行的第三天边的数量加入返回向量中。由于内层循环时间复杂度为O(n),因此用一个循环结构就行,在循环内用if else 语句对第二条边做修改。
  2. 在一些重复的计算出现时,对算法进行一些优化,虽然可能会使逻辑更复杂,代码量增加,但是的的确确会大大减少时间复杂度,在工业上时肯定有用的,本题在找最短边时,如果出现重复的相同边,就找只包含一条该边所能形成的三角形个数和包含两条该边所能形成的三角形个数。然后用排列组合的方法,Cn1, Cn2, Cn3,分别代表取一条边,两条边,三条同样的边来构造得到全部的数量。
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

解题思路:

  1. 使用递归的方法来构造两个树合成的树,如果对应的结点都为NULL,那么返回NULL;如果只有一个为NULL,那么将根结点赋为另一个结点的val值;如果两个都不为NULL,那么将两个结点之和赋给根结点。再递归调用原函数求其左子树和右子树,由于NULL结点的左子结点和右子结点都不存在,因此需要分情况,将参数直接赋为NULL。

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:

  1. The number of tasks is in the range [1, 10000].
  2. The integer n is in the range [0, 100].
解题思路:
  1. 首先从原数组中找出重复次数最多的那个字母(代表任务),最多的任务次数k决定中间至少需要间隔的时间为(k-1)*n,剩下的任务优先填补这些interval,依次填补决定了这些任务之间的间隔一定是足够的,与最多的那个任务一致。如果其他任务的数量是大于等于interval的数量的,那么不需要用idle用填补那些冷却时间,CPU执行时间即为任务的个数;否则CPU执行时间应该为任务的个数加上剩下的interval时间。
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:

  1. The given d is in range [1, maximum depth of the given tree + 1].
  2. The given binary tree has at least one tree node.

解题思路:

  1. 利用队列进行层序遍历,将第给定层d的上一层的结点存储进队列中后跳出循环,然后将队列中的所有结点的左右子树指向新生成的结点(val值为给定值),左子结点的左子树为原本的左子树,右子结点的右子树为原本的右子树。
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:

  1. The length of the given array will be in range [3,104] and all elements are in the range [-1000, 1000].
  2. Multiplication of any three numbers in the input won't exceed the range of 32-bit signed integer.

解题思路:

  1. 可以对原数组进行排序,取最小的两个值(可能为负)与最大值的乘积以及最大的三个正数乘积相比的较大值。
  2. 也可以定义五个变量分别表示上述的值,用一次遍历数组来判断维护。
629. K Inverse Pairs Array

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 be 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:

  1. The integer n is in the range [1, 1000] and k is in the range [0, 1000].

解题思路:

  1. 动态规划的思路没有错,用 dp[i][j] 表示前i个数(即1~i)组成的反转对数为j的排列个数。那么将数i+1插入到前面序列的不同位置上,可以得到各种反转数的序列,因为新插入的数大于前面的所有数,其插入位置不同可以引入 0~i 个反转对数。因此使用双层循环分别对插入数的个数和得到的反转对数做循环。
  2. 如果对于某一反转对数,继续对少一个数得到的不同反转对数做循环,仍然会导致TLE问题。因此我们要定义一个变量做积累,避免每次都重复计算,只有当求的元素对应j比较大,由少一个元素时的较少排列对数插入一个数时得不到时需要减去前面的累积。因此插入这个数i最多引入 i-1 个反转对数,即 pre_j + i - 1 < j,为 pre_j <= j-i 时,需要减去。注意在需要对最后结果取余的相减时一定要事先加上这个base,防止减去后得到的结果为负。因为最后结果肯定是正的。
刷题记录:
  1. 很多陷阱的问题,NO BUG FREE
630. Course Schedule III

There are n different online courses numbered from 1 to n. Each course has some duration(course length) t and closed on dthday. 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:

  1. The integer 1 <= d, t, n <= 10,000.
  2. You can't take two courses simultaneously.

解题思路:

  1. 考虑两个course来说,如果前一个course的结束时间是早于后一个course的情况下,如果前一个course能够及时完成,那么优先完成前一个course的方式得到的是最优解。也就是说优先完成结束时间靠前的course的方式是最好的,因此我们将原向量按照course结束时间的增序重排,依次进行迭代,在能完成当前course的情况下,优先完成。
  2. 在迭代的过程中,如果不能及时完成当前course,即 time + duration > end_time 时,可以考虑取消前面某个课程的学习转而学习当前课程。既然是取消一门课,从而完成当前course,课程数量不变,那么最优化的方向转变到总耗时最短,留下更多的时间来完成之后的course。如果前面完成的所有课程的 duration 均小于等于当前的 duration,那么时间上并没有增加,所有没有必要替换;如果存在比当前course的duration大的课程,那么取其最大的那个课程进行替换,时间的收益是最大化的。而且进行替换后,time - max_pre_duration + cur_duration < time <= pre_endtime <= cur_endtime,所以取消前面课程的学习,当前课程是一定能够完成的,而且用时减少。
  3. 所以定义一个优先级队列(或者在原向量的前面维护一个已完成的课程信息,并用整型变量指定数量),优先级队列可以直接取最大值,向量需要遍历取大于当前duration的最大值,然后进行替换即可,替换后的课程数量不变,将时间减去两者的差值,为后面的课程留下更充裕的时间。
刷题记录:
  1. NO BUG FREE
  2. 不同的解题方法有这样的递进规律:Brute Force 暴力解法,列举所有的可能再讨论 -> 直接递归 -> 带有记忆的递归,存储中间结果,避免重复递归 -> 迭代 -> 动态规划。每种方法都可以进一步考虑优化和存储的问题。
  3. 对于各种递归的时间复杂度分析,要作为专题来研究。
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 klists.

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:

  1. The given list may contain duplicates, so ascending order means >= here.
  2. 1 <= k <= 3500
  3. -105 <= value of elements <= 105.
  4. 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. 对于所有向量,首先取其第一个元素做比较,取其最小值和最大值,那么由这两个值所构成的范围为符合要求的初始化范围。然后将其最小的元素对应向量中的位置往后移一位,加入其后的一个元素,再次取最小值和最大值与之前的范围进行比较。
  2. 由于每次只引入比原来最小值稍大的一位数,因此只需要将之前的最大值与这个引入的值做比较就可以得到新的最大值,同时用优先级队列存储当前考虑的每个向量的一个元素,可以立即得到最小值。另外,需要维护一个向量用来指示当前加入到优先级队列中的每个向量中的元素位置。
  3. 使用优先级队列有个小技巧是,不一定非得存入比较的元素,只要自己定义比较函数即可。例如:优先级队列中可以存储的是元素下标,但是比较的却是对应元素本身。
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. 通过观察,其实a和b至少有一个是在sqrt(c/2)范围内的,因此在这个范围内循环对a循环即可。然后判断c-a^2是否为平方数,判断的方法一种是使用sqrt求得int数后判断平方是否等于原数,或者是用double保存sqrt的结果,然后判断取整后和原double是否相同。
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:

  1. Input logs will be sorted by timestamp, NOT log id.
  2. Your output should be sorted by function id, which means the 0th element of your output corresponds to the exclusive time of function 0.
  3. Two functions won't start or end at the same time.
  4. Functions could be called recursively, and will always end.
  5. 1 <= n <= 100

解题思路:

  1. 定义一个栈来存储依次调用的函数id及其开始时间。如果当前记录为start记录时,新建一个结构变量加入到栈中;如果当前记录为end记录,那么将栈顶结点出栈,并用结束时间-开始时间作为持续时间加入到该id对应的执行时间中去。并且如果栈不为空,说明该函数是由父函数调用执行的,因此该函数的这一次的执行时间不应该计入父函数的执行时间中,因此在新的栈顶结点对应id的function执行时间中减去本次出栈function的起止时间差。
  2. 也可以将start时间和end时间作为结点,通过记录prev对时间分片,分别对当前和其父函数执行相应的操作。
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:

  1. The range of node's value is in the range of 32-bit signed integer.

解题思路:

  1. 利用层序遍历的方法对每层的结点值求和,然后取平均后将结果加入到返回向量中。
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:

  1. There are at most 6 kinds of items, 100 special offers.
  2. For each item, you need to buy at most 6 of them.
  3. You are not allowed to buy more items than you want, even if that would lower the overall price.

解题思路:

  1. 思路比较直接,就是通过递归的方法,尝试所有可能的组合,来得出最小值。注意做是否可能买当前offer的判断,保证得到的item不会超出。另外,special offer 可能比原价购买还要贵,所以每种情形下斗必须与原价购买所有的item所需的金钱做比较,取最小值返回。
  2. 另外,本题的状态不容易出现重复,且描述复杂,因此不需要存储递归结果。
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:

  1. The length of the input string will fit in range [1, 105].
  2. The input string will only contain the character '*' and digits '0' - '9'.

解题思路:

  1. 用动态规划的方法,每次将考虑的字符串长度往后增加一位,根据这一位的字符和前一位的字符来确定动态关系表达式。我是将前一个位置上的字符优先分类考虑的,这个题如果对当前位置上的字符做是否为'*'的考虑代码程序会更简单一点。
  2. 设dp[i]为长度为i的字符串所能解码生成的符号串个数。如果当前位置i上的字符为'*',那么首先dp[i+1] += 9 * dp[i],因为'*'可以当作'1'~'9'任一独立字符,其次根据前面字符为'1','2'或'*'字符可以与当前字符组合起来的情况作考虑;如果当前字符不为'*',即在'0'~'9'之间。如果当前字符为'0',那么dp[i+1]初始化为0,因为'0'只能与前面的符号进行组合,否则初始化为dp[i],如果当前字符为'1'~'9',再根据前面字符为'1','2'或者'*'的情况进行考虑。
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"

解题思路:

  1. 定义一个函数读取左边或者右边表达式中x的系数和,还有常数项的和,返回这两个值所组成的pair<int, int>对。然后根据左边方程和右边方程的系数和常数之间的关系进行判断结果。
  2. 要注意的是边界条件一定要弄清楚,比如说以一个常数作为表达式结尾的情况,需要最后把数值加上去。
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. 1 <= k <= n <= 30,000.
  2. Elements of the given array will be in the range [-10,000, 10,000].
解题思路:
  1. 使用长度为k的滑动窗口求和最大的窗口,将其除以k即为最大的平均数。
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. 1 <= k <= n <= 10,000.
  2. Elements of the given array will be in range [-10,000, 10,000].
  3. The answer with the calculation error less than 10-5 will be accepted.

解题思路:

  1. 此题的思路是在可能的平均值范围内搜索最大的平均值。首先定义返回值的范围,最大值为数组中出现的最大整数,最小值为数组中的最小整数。然后用二分法对其中可能的平均值进行判断。
  2. 判断的过程是找是否有长度大于等于k的子数组的平均值是大于等于目标数的(也就是low和high的中值),用到的方法是类似于之前子数组求和的方式。用一个变量保存从数组头部到位置i的和,用pre_min表示在0~i-k范围内的最小数组和,因为子数组的长度必须是大于等于k的,如果子数组和大于等于mid*长度的,那么返回true,将low改写为当前的mid,反之将high改写为mid。
  3. 由于题目中对结果的精度有要求,那么在进行二分查找时,我们还需要对前一次结果和当前结果之间的差值进行判断,如果小于给定精度则返回结果。
刷题记录:
  1. NO BUG FREE。答案方法中不论是思路的转变、对精度的处理和对子数组和是否能达到给定值判断的方法都很棒。
 
-----------------
涉及 LeetCode 的博文写到这里就暂时告一段落了,愿天道酬勤,继续努力。  2017.7.23 10:37
原文地址:https://www.cnblogs.com/hopelee/p/7118529.html