干掉Leetcode

381 阅读35分钟

Js源码

github.com/zsjun/leetc…

Array

719. Find K-th Smallest Pair Distance

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.



思考历程

1 首先想到使用暴力解法,先是全部遍历出来放到一个大小为 k 的数组,当有新的元素来临的时候,然后再插入,一直维持 k 的数组,但是这里有个问题就是当输入的数组少的时候还可以,但是如果数组变大,直接超时。后来想到既然超时,不如用空间换时间,不维持 k 的数组了,到最后一起排序,可是直接把内存爆了。 这个的空间复杂度 O(k) 时间复杂度是 O(kn²)

问题 1 如何节省时间呢,肯定得 n² 获取到数据,或者少于 n²,用个 hash 节省点时间,可是获取 k 还是得要排序插入?

后来去看了题解,才发现原来可以通过最大范围,也就是先把数组排序,然后用数组中的最大减去最小来确定范围,很奇妙

然后就是采用二分方法来查找,不过这里比较绕的就是这段代码 for (let i = 0, j = 0; i < nums.length; i++) { while (j < nums.length && nums[j] - nums[i] <= mid) j++; count += j - i - 1; } 这里其实就是通过两个指针指向数组,两个指针组合就是一个数组对,这里就是通过遍历找到所有的数组对距离小于等于 mid 的数目

15_3Sum

Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

The solution set must not contain duplicate triplets.

Example:

Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is: [ [-1, 0, 1], [-1, -1, 2] ] 思考路程 1 刚开始想用先排序后暴力的解法,可是发现结果很多是重复的,后来想把重复的过滤掉,但是这样的话本来如果数组中有重复的元素,如果给去掉,这就有可能把正确的结果给去掉,比如是-1,-1,2 假设你把-1给去重了,那-1,-1,2 这个正确的结果也就没有了,这样最后的结果肯定也是不正确的

2 后来想先排序然后通过跳表,每次跳过去数组中相同的元素,但是时间复杂度太高,超时

75. Sort Colors

  1. Sort Colors

Given an array with n objects colored red, white or blue, sort them in-place so that objects of the same color are adjacent, with the colors in the order red, white and blue.

Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.

Note: You are not suppose to use the library's sort function for this problem.

Example:

Input: [2,0,2,1,1,0] Output: [0,0,1,1,2,2] Follow up:

A rather straight forward solution is a two-pass algorithm using counting sort. First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's. Could you come up with a one-pass algorithm using only constant space?

思考路程 1 这个很简单,但是写起来很多细节需要考虑,思路大体上利用两个指针,从两边往中间走,如果发现 2,就移动到后边,发现 0 就移动到前面 2 遍历一遍,如果发现 2 则移动到后面,如果发现 0 则移动到前面,相比第一种方法,这种避免了很多无用的判断,简单粗暴 时间复杂度 O(n) 空间复杂度 O(1)

128. Longest Consecutive Sequence

  1. Longest Consecutive Sequence

Given an unsorted array of integers, find the length of the longest consecutive elements sequence.

Your algorithm should run in O(n) complexity.

Example:

Input: [100, 4, 200, 1, 3, 2] Output: 4 Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.

思考路程 1 利用空间换时间,用一个大数组,遍历数组,然后把每个数组,找到每个元素,然后把元素放到大数组中该元素的值减去1的位置, 然后再遍历该大数组,找到最大的连续子数组,但是这里还有0和负数的情况,不是很好处理。 2 利用数组排序,可是排序一般都是O(nlogn), 因为我们只需要找到最大连续数组的长度就可以了,肯定有许多浪费的时间, 3 想起了以前做过的题目,求数组的最大面积是根据每个数组元素来确定的,可以利用同样的思想,找到每个数组中比它大的和比它小的,就可以了。

380. Insert Delete GetRandom O(1)

  1. Insert Delete GetRandom O(1)

Design a data structure that supports all following operations in average O(1) time.

1 insert(val): Inserts an item val to the set if not already present. 2 remove(val): Removes an item val from the set if present. 3 getRandom: Returns a random element from current set of elements (it's guaranteed that at least one element exists when this method is called). Each element must have the same probability of being returned.

Example: // Init an empty set. RandomizedSet randomSet = new RandomizedSet();

// Inserts 1 to the set. Returns true as 1 was inserted successfully. randomSet.insert(1);

// Returns false as 2 does not exist in the set. randomSet.remove(2);

// Inserts 2 to the set, returns true. Set now contains [1,2]. randomSet.insert(2);

// getRandom should return either 1 or 2 randomly. randomSet.getRandom();

// Removes 1 from the set, returns true. Set now contains [2]. randomSet.remove(1);

// 2 was already in the set, so return false. randomSet.insert(2);

// Since 2 is the only number in the set, getRandom always return 2. randomSet.getRandom();

思考路程 1 可以使用map,这样获取和添加都是O(1),如果获取的话,可以使用Math.random()

2 利用两个map 互相指向,这样稍微可以加快速度

心得

1 可以利用空间来换取时间,比如可以通过两个map来互反,这样就可以让时间加快一些

457. Circular Array Loop

  1. Circular Array Loop

You are given a circular array nums of positive and negative integers. If a number k at an index is positive, then move forward k steps. Conversely, if it's negative (-k), move backward k steps. Since the array is circular, you may assume that the last element's next element is the first element, and the first element's previous element is the last element.

Determine if there is a loop (or a cycle) in nums. A cycle must start and end at the same index and the cycle's length > 1. Furthermore, movements in a cycle must all follow a single direction. In other words, a cycle must not consist of both forward and backward movements.

Example 1:

Input: [2,-1,1,2,2] Output: true Explanation: There is a cycle, from index 0 -> 2 -> 3 -> 0. The cycle's length is 3. Example 2:

Input: [-1,2] Output: false Explanation: The movement from index 1 -> 1 -> 1 ... is not a cycle, because the cycle's length is 1. By definition the cycle's length must be greater than 1.

Example 3:

Input: [-2,1,-1,-2,-2] Output: false Explanation: The movement from index 1 -> 2 -> 1 -> ... is not a cycle, because movement from index 1 -> 2 is a forward movement, but movement from index 2 -> 1 is a backward movement. All movements in a cycle must follow a single direction.

Note:

-1000 ≤ nums[i] ≤ 1000 nums[i] ≠ 0 1 ≤ nums.length ≤ 5000

思考路程 1 看到形成闭环,首先想到了如何判断一个链表是闭环的题目,但是这里好像不知道如何使用。 2 使用回溯法,也就是暴力法,一遍遍的重试,直到找到或者找不到 3 看了题解,有两个疑问, 3.1 如何一个指针走一步,另外一个指针走两步? 理解错了题目,以为是当nums[i] = k的时候,可以向前面走<=k的任何步骤,如果是一定可以走k步,那肯定可以用验证一个链表是不是闭环的方法

79. Word Search

  1. Word Search

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

Example:

board = [ ['A','B','C','E'], ['S','F','C','S'], ['A','D','E','E'] ]

Given word = "ABCCED", return true. Given word = "SEE", return true. Given word = "ABCB", return false.

Constraints:

board and word consists only of lowercase and uppercase English letters. 1 <= board.length <= 200 1 <= board[i].length <= 200 1 <= word.length <= 10^3

思考路程 1 就是类似深度搜索,当搜索不到的时候,返回上一步重新搜索,直到全部搜索完毕,如果没有发现结果,则返回false,否则返回true

1488._Avoid_Flood_in_The_City

Your country has an infinite number of lakes. Initially, all the lakes are empty, but when it rains over the nth lake, the nth lake becomes full of water. If it rains over a lake which is full of water, there will be a flood. Your goal is to avoid the flood in any lake.

Given an integer array rains where:

rains[i] > 0 means there will be rains over the rains[i] lake. rains[i] == 0 means there are no rains this day and you can choose one lake this day and dry it. Return an array ans where:

ans.length == rains.length ans[i] == -1 if rains[i] > 0. ans[i] is the lake you choose to dry in the ith day if rains[i] == 0. If there are multiple valid answers return any of them. If it is impossible to avoid flood return an empty array.

Notice that if you chose to dry a full lake, it becomes empty, but if you chose to dry an empty lake, nothing changes. (see example 4)

Example 1:

Input: rains = [1,2,3,4] Output: [-1,-1,-1,-1] Explanation: After the first day full lakes are [1] After the second day full lakes are [1,2] After the third day full lakes are [1,2,3] After the fourth day full lakes are [1,2,3,4] There's no day to dry any lake and there is no flood in any lake. Example 2:

Input: rains = [1,2,0,0,2,1] Output: [-1,-1,2,1,-1,-1] Explanation: After the first day full lakes are [1] After the second day full lakes are [1,2] After the third day, we dry lake 2. Full lakes are [1] After the fourth day, we dry lake 1. There is no full lakes. After the fifth day, full lakes are [2]. After the sixth day, full lakes are [1,2]. It is easy that this scenario is flood-free. [-1,-1,1,2,-1,-1] is another acceptable scenario. Example 3:

Input: rains = [1,2,0,1,2] Output: [] Explanation: After the second day, full lakes are [1,2]. We have to dry one lake in the third day. After that, it will rain over lakes [1,2]. It's easy to prove that no matter which lake you choose to dry in the 3rd day, the other one will flood. Example 4:

Input: rains = [69,0,0,0,69] Output: [-1,69,1,1,-1] Explanation: Any solution on one of the forms [-1,69,x,y,-1], [-1,x,69,y,-1] or [-1,x,y,69,-1] is acceptable where 1 <= x,y <= 10^9 Example 5:

Input: rains = [10,20,20] Output: [] Explanation: It will rain over lake 20 two consecutive days. There is no chance to dry any lake.

Constraints:

1 <= rains.length <= 10^5 0 <= rains[i] <= 10^9

思考路程 1 不管从前遍历还是从后遍历,如果遇到0,必须往前查看是否是出现过,首先把出现过的,dry,然后才能确定最大概率不出现flood, 这是一种暴力解法

2 题解

When drying a lake #L, it is only useful to dry it if it is FULL already. Otherwise its of no use. (Explained this in the code with a small example as well.) Which lake to dry on a day when there is no rain, can not be determined without knowing the rain sequence that is coming next. For example - If you have rains = [1, 2, 0, ??]. Without knowing what the '??' is, you can not determine which lake to dry on the 3rd day (rains[2]), this is because if '??' = 1, then you must dry the lake #1 to avoid flooding. Similarly, if '??' =2, then you must dry lake #2 to avoid flooding.

思路是一样的,所以关键就是如何确定如何在某天不下雨的时候,如何根据后面要下的雨来决定在不下雨的这天,决定dry 那个湖水。

看到了map和set,其实也就是一个查找和替换的过程,但是发现在leetcode上超时了,js确实慢

后来换了一个思路,可以利用一个数组dryDays,把rains中的不下雨的天数,比如加入第三天没下雨,则设置dryDays[2] = 0, 当在后面出现下雨的时候,然后通过indexOf在drysDasy 查找第一次出现0的情况来替换。

16_3Sum_Closest

Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

Example 1:

Input: nums = [-1,2,1,-4], target = 1 Output: 2 Explanation: The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

Constraints:

3 <= nums.length <= 10^3 -10^3 <= nums[i] <= 10^3 -10^4 <= target <= 10^4

思考路程 1 这个没有什么,和15 3sum 很类似,直接用15 3sum 就可以了

55_Jump_Game

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Determine if you are able to reach the last index.

Example 1:

Input: nums = [2,3,1,1,4] Output: true Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index. Example 2:

Input: nums = [3,2,1,0,4] Output: false Explanation: You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index.

Constraints:

1 <= nums.length <= 3 * 10^4 0 <= nums[i][j] <= 10^5

思考路程 1 因为以前做过动态规划的爬楼梯题目,所以很容易想到了类似的思路

84_Largest_Rectangle_in_Histogram

Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram.

Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3].

The largest rectangle is shown in the shaded area, which has area = 10 unit.

Example:

Input: [2,1,5,6,2,3] Output: 10

思考路程

287. Find the Duplicate Number

  1. Find the Duplicate Number

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.

Example 1:

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

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

You must not modify the array (assume the array is read only). You must use only constant, O(1) extra space. Your runtime complexity should be less than O(n2). There is only one duplicate number in the array, but it could be repeated more than once.

思考路程 1 先排序,然后遍历就可以了,但是数组是只读的,这样明显不可行 2 可以直接使用暴力方法,通过两层遍历来解决 算法复杂度 O(n2) 空间复杂度 O(1) 3 采用龟兔赛跑算法 算法复杂度 O(n)空间复杂度 0(1)

41. First Missing Positive

  1. First Missing Positive Hard

3430

785

Add to List

Share Given an unsorted integer array, find the smallest missing positive integer.

Example 1:

Input: [1,2,0] Output: 3 Example 2:

Input: [3,4,-1,1] Output: 2 Example 3:

Input: [7,8,9,11,12] Output: 1 Note:

Your algorithm should run in O(n) time and uses constant extra space.

思考路程 看到使用O(n)肯定就知道是遍历一遍或者是多遍,可是一直没有想出来如何确定数组中每个元素确定的最小没有出现的正整数如何判断它在前面没有出现.

1 第一种思路是想用两个指针向中间遍历,然后那边大,就移动大的一边,可是还是没有解决如何判断现在的正整数没有出现的问题。

2 第二种思路是想着从0开始遍历数组,找到最小的正整数之后,把该数组放到找到的正整数的位置,可是想着就感觉处理的情况太多,直接放弃。 如果一个算法,要处理的边界情况太多,基本就说明这个算法是错误的。

3 第三种思路看到题解,才明白,首先遍历一遍数组,现在不是先找最小正整数,而是根据数组元素的值来确定该数组元素的位置,比如现在数组元素的值是5,就把它放到数组中第四的位置,这样过一遍之后,然后再第二次遍历数组,如果发现当前的数组元素的值不是数组元素的下标 i+1, 则返回i+1, 否则返回n+1

这种妙在数组元素的下标天然可以和最小正整数对应起来。

写一个完全正确的算法确实很难

719. Find K-th Smallest Pair Distance

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.

思考历程

1 首先想到使用暴力解法,先是全部遍历出来放到一个大小为 k 的数组,当有新的元素来临的时候,然后再插入,一直维持 k 的数组,但是这里有个问题就是当输入的数组少的时候还可以,但是如果数组变大,直接超时。后来想到既然超时,不如用空间换时间,不维持 k 的数组了,到最后一起排序,可是直接把内存爆了。 这个的空间复杂度 O(k) 时间复杂度是 O(kn²)

问题 1 如何节省时间呢,肯定得 n² 获取到数据,或者少于 n²,用个 hash 节省点时间,可是获取 k 还是得要排序插入?

后来去看了题解,才发现原来可以通过最大范围,也就是先把数组排序,然后用数组中的最大减去最小来确定范围,很奇妙

然后就是采用二分方法来查找,不过这里比较绕的就是这段代码 for (let i = 0, j = 0; i < nums.length; i++) { while (j < nums.length && nums[j] - nums[i] <= mid) j++; count += j - i - 1; } 这里其实就是通过两个指针指向数组,两个指针组合就是一个数组对,这里就是通过遍历找到所有的数组对距离小于等于 mid 的数目

162. Find Peak Element

A peak element is an element that is greater than its neighbors.

Given an input array nums, where nums[i] ≠ nums[i+1], find a peak element and return its index.

The array may contain multiple peaks, in that case return the index to any one of the peaks is fine.

You may imagine that nums[-1] = nums[n] = -∞.

Example 1:

Input: nums = [1,2,3,1] Output: 2 Explanation: 3 is a peak element and your function should return the index number 2. Example 2:

Input: nums = [1,2,1,3,5,6,4] Output: 1 or 5 Explanation: Your function can return either index number 1 where the peak element is 2, or index number 5 where the peak element is 6.

Follow up: Your solution should be in logarithmic complexity. 思考路程 1, 第一眼就可以明显的看出,可以直接遍历一遍,只要找到一个峰值,就可以直接返回它的index了,可是题目要求是logn,则必须想别的办法。 2,logn肯定得折半查找,可是怎么折半呢? 刚开始想用空间换时间,可是没有想出来到底该怎么做。 后来想到用跳表,这样来减少需要查找的数目,可是也没想出来到底怎么做。

3,看了题解决,才明白原来可以转化为查找到数组中的最大数目,才发现自己犯了一个错误,想要找出所有的,但是实际上只要在任何一半之内有峰值就可以了。所以可以折半,然后判断两个相邻的,如果大于, 这里还有一个细节就是You may imagine that nums[-1] = nums[n] = -∞. 自己也没有好好注意,还是得把问题搞清楚,然后才能想解决办法

45. Jump Game II

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Your goal is to reach the last index in the minimum number of jumps.

Example:

Input: [2,3,1,1,4] Output: 2 Explanation: The minimum number of jumps to reach the last index is 2. Jump 1 step from index 0 to 1, then 3 steps to the last index. Note:

You can assume that you can always reach the last index.

思考路程 1, 可以利用最后一步,如果向前移动最大,找到下一步,然后下一步再向前移动最大

贪心算法

455. Assign Cookies

Assume you are an awesome parent and want to give your children some cookies. But, you should give each child at most one cookie. Each child i has a greed factor gi, which is the minimum size of a cookie that the child will be content with; and each cookie j has a size sj. If sj >= gi, we can assign the cookie j to the child i, and the child i will be content. Your goal is to maximize the number of your content children and output the maximum number.

Note: You may assume the greed factor is always positive. You cannot assign more than one cookie to one child.

Example 1: Input: [1,2,3], [1,1]

Output: 1

Explanation: You have 3 children and 2 cookies. The greed factors of 3 children are 1, 2, 3. And even though you have 2 cookies, since their size is both 1, you could only make the child whose greed factor is 1 content. You need to output 1. Example 2: Input: [1,2], [1,2,3]

Output: 2

Explanation: You have 2 children and 3 cookies. The greed factors of 2 children are 1, 2. You have 3 cookies and their sizes are big enough to gratify all of the children, You need to output 2.

思考路程 1 很简单,使用贪心算法,就ok了 算法时间复杂度O(nlogn) 空间复杂度O(1)

376. Wiggle Subsequence

A sequence of numbers is called a wiggle sequence if the differences between successive numbers strictly alternate between positive and negative. The first difference (if one exists) may be either positive or negative. A sequence with fewer than two elements is trivially a wiggle sequence.

For example, [1,7,4,9,2,5] is a wiggle sequence because the differences (6,-3,5,-7,3) are alternately positive and negative. In contrast, [1,4,7,2,5] and [1,7,4,5,5] are not wiggle sequences, the first because its first two differences are positive and the second because its last difference is zero.

Given a sequence of integers, return the length of the longest subsequence that is a wiggle sequence. A subsequence is obtained by deleting some number of elements (eventually, also zero) from the original sequence, leaving the remaining elements in their original order.

Example 1:

Input: [1,7,4,9,2,5] Output: 6 Explanation: The entire sequence is a wiggle sequence. Example 2:

Input: [1,17,5,10,13,15,10,5,16,8] Output: 7 Explanation: There are several subsequences that achieve this length. One is [1,17,10,13,10,16,8]. Example 3:

Input: [1,2,3,4,5,6,7,8,9] Output: 2

Follow up: Can you do it in O(n) time?

思考路程 1 首先想到暴力解法,从头开始遍历,然后找到最大的摇摆子序列

算法时间复杂度O(N2) 空间复杂度 O(1)

2 贪心算法,当遇到一直升序的时候,选择最大的元素,当遇到降序排列时候,选择最小的,则最后就可以得到子序列 算法时间复杂度0(n) 空间复杂度O(1)

402. Remove K Digits

Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible.

Note: The length of num is less than 10002 and will be ≥ k. The given num does not contain any leading zero. Example 1:

Input: num = "1432219", k = 3 Output: "1219" Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest. Example 2:

Input: num = "10200", k = 1 Output: "200" Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes. Example 3:

Input: num = "10", k = 2 Output: "0" Explanation: Remove all the digits from the number and it is left with nothing which is 0.

思考路程 1 因为想要最小的,那肯定是高位是越小,则留下的数字越小,利用贪心算法,从高位往后,删掉大的,比如14,则删掉4就可以了

2 按照1的思路写出来,感觉有些测试用例过不了,而且逻辑复杂,自己都搞乱了,后来想了下,应该是如果升序,则删掉最大的,如果是降序,则删掉本身

时间复杂度0(n) 空间复杂度O(n)

心得 1 如果算法自己写起来,感觉逻辑越来越复杂,就说明算法本身有问题,需要重新寻找逻辑

452. Minimum Number of Arrows to Burst Balloons

There are a number of spherical balloons spread in two-dimensional space. For each balloon, provided input is the start and end coordinates of the horizontal diameter. Since it's horizontal, y-coordinates don't matter and hence the x-coordinates of start and end of the diameter suffice. Start is always smaller than end. There will be at most 104 balloons.

An arrow can be shot up exactly vertically from different points along the x-axis. A balloon with xstart and xend bursts by an arrow shot at x if xstart ≤ x ≤ xend. There is no limit to the number of arrows that can be shot. An arrow once shot keeps travelling up infinitely. The problem is to find the minimum number of arrows that must be shot to burst all balloons.

Example:

Input: [[10,16], [2,8], [1,6], [7,12]]

Output: 2

Explanation: One way is to shoot one arrow for example at x = 6 (bursting the balloons [2,8] and [1,6]) and another arrow at x = 11 (bursting the other two balloons).

思考路程 1 既然是用贪心算法,那问题就是如何贪心? 先遍历,按照每个区间最小排序,然后找到最大重合的就可以了。

算法时间复杂度 O(nlgn)空间复杂度 O(1)

心得 1 贪心算法最重要的就是找到是不是适合贪心算法,找到最合适的贪心算法。

hashMap

3. Longest Substring Without Repeating Characters

Given a string, find the length of the longest substring without repeating characters.

Example 1:

Input: "abcabcbb" Output: 3 Explanation: The answer is "abc", with the length of 3. Example 2:

Input: "bbbbb" Output: 1 Explanation: The answer is "b", with the length of 1. Example 3:

Input: "pwwkew" Output: 3 Explanation: The answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.

思考路程 1 这个很简单,利用两个指针,当快指针发现相同元素的时候,慢指针到已经遍历的相同元素的下一个

算法时间复杂度O(n) 空间复杂度O(n)

心得 1 这个应该是以前做过,算法也靠熟练

36. Valid Sudoku

Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules:

Each row must contain the digits 1-9 without repetition. Each column must contain the digits 1-9 without repetition. Each of the 9 3x3 sub-boxes of the grid must contain the digits 1-9 without repetition.

A partially filled sudoku which is valid.

The Sudoku board could be partially filled, where empty cells are filled with the character '.'.

Example 1:

Input: [ ["5","3",".",".","7",".",".",".","."], ["6",".",".","1","9","5",".",".","."], [".","9","8",".",".",".",".","6","."], ["8",".",".",".","6",".",".",".","3"], ["4",".",".","8",".","3",".",".","1"], ["7",".",".",".","2",".",".",".","6"], [".","6",".",".",".",".","2","8","."], [".",".",".","4","1","9",".",".","5"], [".",".",".",".","8",".",".","7","9"] ] Output: true Example 2:

Input: [ ["8","3",".",".","7",".",".",".","."], ["6",".",".","1","9","5",".",".","."], [".","9","8",".",".",".",".","6","."], ["8",".",".",".","6",".",".",".","3"], ["4",".",".","8",".","3",".",".","1"], ["7",".",".",".","2",".",".",".","6"], [".","6",".",".",".",".","2","8","."], [".",".",".","4","1","9",".",".","5"], [".",".",".",".","8",".",".","7","9"] ] Output: false Explanation: Same as Example 1, except with the 5 in the top left corner being modified to 8. Since there are two 8's in the top left 3x3 sub-box, it is invalid. Note:

A Sudoku board (partially filled) could be valid but is not necessarily solvable. Only the filled cells need to be validated according to the mentioned rules. The given board contain only digits 1-9 and the character '.'. The given board size is always 9x9.

思考路程 1 直接遍历就可以了

409. Longest Palindrome

Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters.

This is case sensitive, for example "Aa" is not considered a palindrome here.

Note: Assume the length of given string will not exceed 1,010.

Example:

Input: "abccccdd"

Output: 7

Explanation: One longest palindrome that can be built is "dccaccd", whose length is 7.

思考路程 1, 用一个 map 统计每个字符出现的次数,然后再遍历一遍,如果字符串的长度是偶数,就只提取出现两次的,如果字符串长度是奇数,则提取一次奇数,其他的奇数如果大于 3,则减一加入。

算法时间复杂度 O(n), 空间复杂度 O(n)

心得 1 算法虽然很简单,但是如果写一个可以完全通过测试的还是不容易

76. Minimum Window Substring

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).

Example:

Input: S = "ADOBECODEBANC", T = "ABC" Output: "BANC" Note:

If there is no such window in S that covers all characters in T, return the empty string "". If there is such window, you are guaranteed that there will always be only one unique minimum window in S.

思考路程 1 首先想到用两个指针,一个指在首先发现的地方,然后一直向前遍历,但是这里涉及到了一个更新第一个指针的问题,什么时候更新,更新到什么地方,感觉很麻烦,放弃。 2 后来想到可以用 map 遍历一遍,形成一个类似 hashmap 的,然后遍历需要查找的字符串,找个每个字符开始的最小长度,但是这里有个问题,逻辑搞的很复杂。 3 后来还想到用 lastIndexOf 来找到最后出现的字符,发现好像也没有什么用 4 看了题解,感觉确实牛逼,原理很简单,首先在 s 中发现包含字符串 t 的子串 t1,然后再在 t1 中找到第一次出现在 t 中的字符,比如 a,然后在 s-t 的剩下字符串中查找出现 a 的位置,再更新最小子串距离,如此循环

算法时间复杂度 O(n) 空间复杂度 O(n)

心得 1 利用指针移动获取最小或者最大字符,关键是找到之后,如何恢复成下一次查找

49. Group Anagrams

  1. Group Anagrams

Given an array of strings, group anagrams together.

Example:

Input: ["eat", "tea", "tan", "ate", "nat", "bat"], Output: [ ["ate","eat","tea"], ["nat","tan"], ["bat"] ] Note:

All inputs will be in lowercase. The order of your output does not matter.

思考路程: 1 直接用一个 map 对应一个数组,存在就 push 到数组,不存在就新建一个数组 push 进去 算法时间复杂度O(n)空间复杂度O(n)

TwoPoints

19. Remove Nth Node From End of List

Given a linked list, remove the n-th node from the end of list and return its head.

Example:

Given linked list: 1->2->3->4->5, and n = 2.

After removing the second node from the end, the linked list becomes 1->2->3->5. Note:

Given n will always be valid.

Follow up:

Could you do this in one pass?

思考路程 1 这个很简单,用两个指针,一个快,一个慢,相差 n, 当快指针到头之后,就可以删除对应的元素

算法时间复杂度 O(n)空间复杂度 O(1)

  1. Repeated DNA Sequences

All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA.

Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule.

Example:

Input: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"

Output: ["AAAAACCCCC", "CCCCCAAAAA"]

思考路程 1 很简单,和 49 题目有点类似,用同样的方法,只是这里用到 hashmap,把每个子串都 hash 了,如果出现相同的,则加入到结果中,这里可以使用 Set,刚好可以去掉重复的元素。

使用了 Set 去重 算法时间复杂度 O(nlgn) 空间复杂度 O(n)

DP

70. Climbing Stairs

You are climbing a stair case. It takes n steps to reach to the top.

Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?

Example 1:

Input: 2 Output: 2 Explanation: There are two ways to climb to the top.

  1. 1 step + 1 step
  2. 2 steps Example 2:

Input: 3 Output: 3 Explanation: There are three ways to climb to the top.

  1. 1 step + 1 step + 1 step
  2. 1 step + 2 steps
  3. 2 steps + 1 step

198. House Robber

You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night.

Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police.

Example 1:

Input: nums = [1,2,3,1] Output: 4 Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3). Total amount you can rob = 1 + 3 = 4. Example 2:

Input: nums = [2,7,9,3,1] Output: 12 Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1). Total amount you can rob = 2 + 9 + 1 = 12.

思考路程

1 状态转移,只要知道偷盗隔一个房子和前面房子的的金额,就可以计算出自己本身的金额, 选择最大的就可以了

53. Maximum Subarray

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

Example:

Input: [-2,1,-3,4,-1,2,1,-5,4], Output: 6 Explanation: [4,-1,2,1] has the largest sum = 6. Follow up:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

思考路程

1 初始值 -2, 状态转移 找到以某个数结尾的最大子串,然后状态进行转移

算法复杂度0(n) 时间复杂度O(1)

心得 1 dp 最主要的是找到状态,也就是dp[i] 与dp[i+1] 之间的关系

322. Coin Change

You are given coins of different denominations and a total amount of money amount. Write a function to compute the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.

Example 1:

Input: coins = [1, 2, 5], amount = 11 Output: 3 Explanation: 11 = 5 + 5 + 1 Example 2:

Input: coins = [2], amount = 3 Output: -1 Note: You may assume that you have an infinite number of each kind of coin.

思考路程 1 找到dp[i]和dp[i+1] 之间的关系,首先确定状态是什么? dp[i] 可以是使用金额i 的最小张数 dp[i] = Math.min(dp[i-1], dp[i-2], dp[i-5]) + 1

心得 1 只要找到dp[i] 和前面的dp的关系就ok,不用必须是dp[i] 和dp[i+1] 的关系

300. Longest Increasing Subsequence

Given an unsorted array of integers, find the length of longest increasing subsequence.

Example:

Input: [10,9,2,5,3,7,101,18] Output: 4 Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4. Note:

There may be more than one LIS combination, it is only necessary for you to return the length. Your algorithm should run in O(n2) complexity. Follow up: Could you improve it to O(n log n) time complexity?

思考路程 1 找到dp[i] 和dp[i+1]的关系 dp[i] 可以表示到数组arr[i]的最大升序 则dp[i+1] 就可以从Math.max(dp[i] && arr[i+1]>arr[i], dp[i-1] && arr[i+1]>arr[i-1]...) +1取到

时间复杂度O(n2) 空间复杂度O(n)

64. Minimum Path Sum

Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.

Note: You can only move either down or right at any point in time.

Example:

Input: [ [1,3,1], [1,5,1], [4,2,1] ] Output: 7 Explanation: Because the path 1→3→1→1→1 minimizes the sum.

思考路程 1 dp[i][j] 代表到现在的最小路径值,状态转移 dp[i][j] = Math.min(dp[i-1][j] +dp[i][j], dp[i][j-1] + dp[i][j] )

174. Dungeon Game

The demons had captured the princess (P) and imprisoned her in the bottom-right corner of a dungeon. The dungeon consists of M x N rooms laid out in a 2D grid. Our valiant knight (K) was initially positioned in the top-left room and must fight his way through the dungeon to rescue the princess.

The knight has an initial health point represented by a positive integer. If at any point his health point drops to 0 or below, he dies immediately.

Some of the rooms are guarded by demons, so the knight loses health (negative integers) upon entering these rooms; other rooms are either empty (0's) or contain magic orbs that increase the knight's health (positive integers).

In order to reach the princess as quickly as possible, the knight decides to move only rightward or downward in each step.

Write a function to determine the knight's minimum initial health so that he is able to rescue the princess.

For example, given the dungeon below, the initial health of the knight must be at least 7 if he follows the optimal path RIGHT-> RIGHT -> DOWN -> DOWN.

-2 (K) -3 3 -5 -10 1 10 30 -5 (P)

Note:

The knight's health has no upper bound. Any room can contain threats or power-ups, even the first room the knight enters and the bottom-right room where the princess is imprisoned.

思考路程 1 和 64 类似,只不过从最下往上走

Linked List

206. Reverse Linked List

Reverse a singly linked list.

Example:

Input: 1->2->3->4->5->NULL Output: 5->4->3->2->1->NULL Follow up:

A linked list can be reversed either iteratively or recursively. Could you implement both?

思考路程 1 用一个额外数组,或者用两个指针

92. Reverse Linked List II

Reverse a linked list from position m to n. Do it in one-pass.

Note: 1 ≤ m ≤ n ≤ length of list.

Example:

Input: 1->2->3->4->5->NULL, m = 2, n = 4 Output: 1->4->3->2->5->NULL

思考路程 1 这题标记是简单,但是还是没搞出来,本来想先逆转一个链表,然后再寻找,发现这样根本不行

2 看了题解,才明白,可以通过计算 headA 和 headB 走的路程来计算出位置,这有点和龟兔赛跑算法有点类似, 简直太牛逼了。这里我也想到了龟兔赛跑算法,但是没有想出来根据距离来确定位置。

141. Linked List Cycle

Given a linked list, determine if it has a cycle in it.

To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

Example 1:

Input: head = [3,2,0,-4], pos = 1 Output: true Explanation: There is a cycle in the linked list, where tail connects to the second node.

Example 2:

Input: head = [1,2], pos = 0 Output: true Explanation: There is a cycle in the linked list, where tail connects to the first node.

Example 3:

Input: head = [1], pos = -1 Output: false Explanation: There is no cycle in the linked list.

Follow up:

Can you solve it using O(1) (i.e. constant) memory?

思考路程 1 利用两个指针,如果快指针追上慢指针就证明有环 算法时间复杂度0(n) 空间复杂度O(1)

86. Partition List

Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.

You should preserve the original relative order of the nodes in each of the two partitions.

Example:

Input: head = 1->4->3->2->5->2, x = 3 Output: 1->2->2->4->3->5

思考路程

1 利用两个指针,一个 slow,指向最后一个小于等于 val 的元素,一个 fast 指向大于等于 val 的最后一个元素指针,直到 fast 到末尾

心得 1 链表需要画图, 2 首先把逻辑想清楚,然后再做,不然修修补补很麻烦

138. Copy List with Random Pointer

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.

The Linked List is represented in the input/output as a list of n nodes. Each node is represented as a pair of [val, random_index] where:

val: an integer representing Node.val random_index: the index of the node (range from 0 to n-1) where random pointer points to, or null if it does not point to any node.

Example 1:

Input: head = [[7,null],[13,0],[11,4],[10,2],[1,0]] Output: [[7,null],[13,0],[11,4],[10,2],[1,0]] Example 2:

Input: head = [[1,1],[2,1]] Output: [[1,1],[2,1]] Example 3:

Input: head = [[3,null],[3,0],[3,null]] Output: [[3,null],[3,0],[3,null]] Example 4:

Input: head = [] Output: [] Explanation: Given linked list is empty (null pointer), so return null.

Constraints:

-10000 <= Node.val <= 10000 Node.random is null or pointing to a node in the linked list. Number of Nodes will not exceed 1000.

思考路程 1 直接复制,第一遍先复制单链表,第二遍复制 random_index 链表,利用 map 2 利用原来的链表,直接复制到现在的链表上,然后再取出节点

算法时间复杂度 O(n)空间复杂度 O(1)

21. Merge Two Sorted Lists

Merge two sorted linked lists and return it as a new sorted list. The new list should be made by splicing together the nodes of the first two lists.

Example:

Input: 1->2->4, 1->3->4 Output: 1->1->2->3->4->4

思考路程

1 两个指针,直接合并到一个链表上就可以了。

78. Subsets

Given a set of distinct integers, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

Example:

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

思考路程 1

90. Subsets II

Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set).

Note: The solution set must not contain duplicate subsets.

Example:

Input: [1,2,2] Output: [ [2], [1], [1,2,2], [2,2], [1,2], [] ]

思考路程 1 这里和 78 类似,只不过加一些条件就好了

40. Combination Sum II

Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

Each number in candidates may only be used once in the combination.

Note:

All numbers (including target) will be positive integers. The solution set must not contain duplicate combinations. Example 1:

Input: candidates = [10,1,2,7,6,1,5], target = 8, A solution set is: [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ] Example 2:

Input: candidates = [2,5,2,1,2], target = 5, A solution set is: [ [1,2,2], [5] ]

思考路程 1 参考第 40 题,找出所有的子集,然后确定是不是等于 target, 刚开始写完简单还好,但是数组长了,执行时间成倍增长,刚开始以为死循环了,后来发现不是死循环,是执行时间太长了

时间复杂度 O(2ⁿ)

46. Permutations

Given a collection of distinct integers, return all possible permutations.

Example:

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

思考路程 1 依然使用 78 的题目解法,只是加一些条件,可是怎么修改条件呢?

只要把已经用过的从传入的数组中去掉就可以了,还是使用递归

47. Permutations II

Given a collection of numbers that might contain duplicates, return all possible unique permutations.

Example:

Input: [1,1,2] Output: [ [1,1,2], [1,2,1], [2,1,1] ]

思考过程 1 参考 46, 只是加一些条件把重复的过滤掉就可以了

39. Combination Sum

Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target.

The same repeated number may be chosen from candidates unlimited number of times.

Note:

All numbers (including target) will be positive integers. The solution set must not contain duplicate combinations. Example 1:

Input: candidates = [2,3,6,7], target = 7, A solution set is: [ [7], [2,2,3] ] Example 2:

Input: candidates = [2,3,5], target = 8, A solution set is: [ [2,2,2,2], [2,3,3], [3,5] ]

Constraints:

1 <= candidates.length <= 30 1 <= candidates[i] <= 200 Each element of candidate is unique. 1 <= target <= 500

思考路程 1 一样的思路,和 46 题目,利用回溯和递归法

131. Palindrome Partitioning

Given a string s, partition s such that every substring of the partition is a palindrome.

Return all possible palindrome partitioning of s.

Example:

Input: "aab" Output: [ ["aa","b"], ["a","a","b"] ]

思考路程 1 和 46 等题目一样,利用回溯法和递归,符合条件的就加入