leetcode笔记—Array

1. Two Sum (easy)

找到数组中和为target的两个数,返回索引

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:
Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
problem
 1 class Solution {
 2 public:
 3     vector<int> twoSum(vector<int>& nums, int target) {
 4         unordered_map<int, int> hash;
 5         vector<int> result;
 6         for (int i = 0; i < nums.size(); i++) {
 7             if (hash.find(target - nums[i]) != hash.end()) {
 8                 result.push_back(hash[target - nums[i]]);
 9                 result.push_back(i);
10                 return result;
11             }
12             hash[nums[i]] = i;
13         }
14         return result;
15     }
16 };
View Code

 


4. Median of Two Sorted Arrays (hard)

找到两个排序好的数组的中位数

There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

Example 1:
nums1 = [1, 3]
nums2 = [2]

The median is 2.0
Example 2:
nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5
problem
 1 // 思路:让length1<length2,对于第一个数组的index1,取左右为L1,R1(index1为R1的索引),第二个数组的L2,R2,当max(L1,L2)<min(R1,R2),则找到。对index1进行二分查找,那么index2 = (length1+length2+1)/2-index1.
 2 class Solution {
 3 public:
 4     double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
 5         int n1 = nums1.size(), n2 = nums2.size(), l1 = n1/2, l2 = (n1 + n2)/2 - 2 - l1;
 6         if (n1 > n2)
 7             return findMedianSortedArrays(nums2, nums1);
 8         int left = -1, right = n1;
 9         while (left <= right) {
10             l1 = (left + right)/2;
11             l2 = (n1 + n2 + 1)/2 - l1;
12             int L1 = l1 <= 0 ? INT_MIN : nums1[l1 - 1];
13             int R1 = l1 >= n1 ? INT_MAX : nums1[l1];
14             int L2 = l2 <= 0 ? INT_MIN : nums2[l2 - 1];
15             int R2 = l2 >= n2 ? INT_MAX : nums2[l2];
16             if (L1 > R2)
17                 right = l1 - 1;
18             else if (L2 > R1)
19                 left = l1 + 1;
20             else
21                 return (n1 + n2)%2 == 1 ? 1.0*max(L1, L2) : 1.0*(max(L1, L2) + min(R1, R2))/2;
22         }
23         return (n1 + n2)%2 == 1 ? nums2[l2] : 1.0*(nums2[l2] + nums2[l2 - 1])/2;
24     }
25 };
View Code

 


11. Container With Most Water (medium)

 数组中每个元素代表容器一边的高度,两元素的距离代表容器的宽度,找到两个边使容器容量最高

Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.

Note: You may not slant the container and n is at least 2.
problem
 1 // 思路:从两边往中间走,高度低于之前高度的可直接跳过
 2 class Solution {
 3 public:
 4     int maxArea(vector<int>& height) {
 5         int left = 0, right = height.size() - 1, res = 0;
 6         while (left < right) {
 7             int side = min(height[left], height[right]);
 8             res = max(res, side*(right - left));
 9             while (height[left] <= side) left++;
10             while (height[right] <= side) right--;
11         }
12         return res;
13     }
14 };
View Code

 


15. 3 Sum (medium)

 找到数组中所有的 和为0的 三元数组。

Given an array S of n integers, are there elements a, b, c in S 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.

For example, given array S = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]
problem
 1 // 思路:排序后index1从小到大,index2和index3从两边到中间
 2 class Solution {
 3 public:
 4     vector<vector<int>> threeSum(vector<int>& nums) {
 5         vector<vector<int>> res;
 6         int length = nums.size();
 7         sort(nums.begin(), nums.end());
 8         for (int i = 0; i < length - 2 && nums[i] <= 0; ++i) {
 9             if (i > 0 && nums[i] == nums[i - 1]) continue;
10             int target = -nums[i], left = i + 1, right = length - 1;
11             while (left < right) {
12                 if (nums[left] + nums[right] < target) ++left;
13                 else if (nums[left] + nums[right] > target) --right;
14                 else {
15                     vector<int> tmp(3);
16                     tmp[0] = nums[i];
17                     tmp[1] = nums[left];
18                     tmp[2] = nums[right];
19                     res.push_back(tmp);
20                     while (left < right && nums[left] == tmp[1]) ++left;
21                     while (left < right && nums[right] == tmp[2]) --right;
22                 }
23             }
24         }
25         return res;
26     }
27 };
View Code

 


16. 3Sum Closest (medium)

 找到距离target最近的三元数组,返回三个数的和

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

    For example, given array S = {-1 2 1 -4}, and target = 1.

    The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
problem
 1 // 与3sum类似
 2 class Solution {
 3 public:
 4     int threeSumClosest(vector<int>& nums, int target) {
 5         sort(nums.begin(), nums.end());
 6         int dis = INT_MAX, res = 0, length = nums.size();
 7         for (int i = 0; i < length - 2; ++i) {
 8             int left = i + 1, right = length - 1, t = target - nums[i];
 9             while (left < right) {
10                 int sum = nums[left] + nums[right];
11                 if (abs(sum - t) < dis) {
12                     dis = abs(sum - t);
13                     res = nums[i] + sum;
14                 }
15                 if (sum < t)
16                     ++left;
17                 else if (sum > t)
18                     --right;
19                 else
20                     return target;
21             }
22         }
23         return res;
24     }
25 };
View Code

 


18. 4Sum (medium)

找到所有和为target的四元数组

Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note: The solution set must not contain duplicate quadruplets.

For example, given array S = [1, 0, -1, 0, -2, 2], and target = 0.

A solution set is:
[
  [-1,  0, 0, 1],
  [-2, -1, 1, 2],
  [-2,  0, 0, 2]
]
problem
 1 class Solution {
 2 public:
 3     vector<vector<int>> fourSum(vector<int>& nums, int target) {
 4         vector<vector<int>> res;
 5         if (nums.size() < 4) return res;
 6         sort(nums.begin(), nums.end());
 7         for (int i = 0; i < nums.size() - 3; ++i) {
 8             if (i > 0 && nums[i] == nums[i - 1]) continue;
 9             vector<vector<int>> tmp = threeSum(nums, target - nums[i], i + 1);
10             for (auto v : tmp)
11                 res.push_back(v);
12         }
13         return res;
14     }
15     
16     vector<vector<int>> threeSum(vector<int>& nums, int t, int start) {
17         vector<vector<int>> res;
18         int length = nums.size();
19         for (int i = start; i < length - 2 && nums[i] <= t/3; ++i) {
20             if (i > start && nums[i] == nums[i - 1]) continue;
21             int target = t - nums[i], left = i + 1, right = length - 1;
22             while (left < right) {
23                 if (nums[left] + nums[right] < target) ++left;
24                 else if (nums[left] + nums[right] > target) --right;
25                 else {
26                     vector<int> tmp(4);
27                     tmp[0] = nums[start - 1];
28                     tmp[1] = nums[i];
29                     tmp[2] = nums[left];
30                     tmp[3] = nums[right];
31                     res.push_back(tmp);
32                     while (left < right && nums[left] == tmp[2]) ++left;
33                     while (left < right && nums[right] == tmp[3]) --right;
34                 }
35             }
36         }
37         return res;
38     }
39 };
View Code

 


26. Remove Duplicates from Sorted Array (easy)

把不重复的元素放在数组最前面,返回不重复元素个数

Given a sorted array, remove the duplicates in-place such that each element appear only once and return the new length.

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

Example:

Given nums = [1,1,2],

Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively.
It doesn't matter what you leave beyond the new length.
problem
 1 class Solution {
 2 public:
 3     int removeDuplicates(vector<int>& nums) {
 4         if (nums.size() < 2) return nums.size();
 5         int j = 1;
 6         for (int i = 1; i < nums.size(); ++i) {
 7             if (nums[i] != nums[i - 1])
 8                 nums[j++] = nums[i];
 9         }
10         return j;
11     }
12 };
View Code

 


27. Remove Element (easy)

 把不等于val的数放在数组的前面,返回其个数

Given an array and a value, remove all instances of that value in-place and return the new length.

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

The order of elements can be changed. It doesn't matter what you leave beyond the new length.

Example:

Given nums = [3,2,2,3], val = 3,

Your function should return length = 2, with the first two elements of nums being 2.
problem
 1 class Solution {
 2 public:
 3     int removeElement(vector<int>& nums, int val) {
 4         int length = 0;
 5         for (int i = 0; i < nums.size(); ++i) {
 6             if (nums[i] != val)
 7                 nums[length++] = nums[i];
 8         }
 9         return length;
10     }
11 };
View Code

 


31. Next Permutation (medium)

下一个排列:nums中的数字组成的数中,比 以原顺序组成的 大的下一个数组

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

The replacement must be in-place, do not allocate extra memory.

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.
1,2,31,3,2
3,2,11,2,3
1,1,51,5,1
problem
 1 // 思路:从后往前,找到第一个非升序的数,跟比他大的第一个数交换,反转后面的数
 2 class Solution {
 3 public:
 4     void nextPermutation(vector<int>& nums) {
 5         int i = nums.size() - 1, j = nums.size() - 1;
 6         while (i > 0 && nums[i] <= nums[i - 1])
 7             --i;
 8         if (i > 0) {
 9             while (nums[j] <= nums[i - 1])
10                 --j;
11             swap(nums[i - 1], nums[j]);
12         }
13         reverse(nums.begin() + i, nums.end());
14     }
15 };
View Code

 


33. Search in Rotated Sorted Array (medium) #

在一个旋转后的有序数列中找到target

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.
problem
 1 // 思路:先找到旋转的长度,然后每次的中点加旋转长度。
 2 // 易错点mid和real_mid
 3 class Solution {
 4 public:
 5     int search(vector<int>& nums, int target) {
 6         int left = 0, right = nums.size() - 1;
 7         while (left < right) {
 8             int mid = (left + right)/2;
 9             if (nums[mid] > nums[right])
10                 left = mid + 1;
11             else
12                 right = mid;
13         }
14         int pivot = left;
15         left = 0;
16         right = nums.size() - 1;
17         while (left <= right) {
18             int mid = (left + right)/2;
19             int real_mid = (mid + pivot)%nums.size();  //
20             if (nums[real_mid] == target)
21                 return real_mid;
22             else if (nums[real_mid] < target)
23                 left = mid + 1;
24             else
25                 right = mid - 1;
26         }
27         return -1;
28     }
29 };
View Code

 


34. Search for a Range (medium)

 找到有序数组中值为target的索引范围

Given an array of integers sorted in ascending order, find the starting and ending position of a given target value.

Your algorithm's runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].
problem
 1 // 思路:先找左,再找右
 2 class Solution {
 3 public:
 4     vector<int> searchRange(vector<int>& nums, int target) {
 5         vector<int> res(2, -1);
 6         int left = 0, right = nums.size() - 1;
 7         while (left < right) {
 8             int mid = (left + right)/2;
 9             if (nums[mid] < target)
10                 left = mid + 1;
11             else
12                 right = mid;
13         }
14         if (right < 0 || nums[left] != target)
15             return res;
16         res[0] = left;
17         right = nums.size() - 1;
18         while (left < right) {
19             int mid = (left + right)/2 + 1;
20             if (nums[mid] > target)
21                 right = mid - 1;
22             else
23                 left = mid;
24         }
25         res[1] = left;
26         return res;
27     }
28 };
View Code

 


35. Search Insert Position (easy)

 有序数组中找target的位置,如果没有,找到应该插入的位置

Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

You may assume no duplicates in the array.

Example 1:

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

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

Input: [1,3,5,6], 7
Output: 4
Example 1:

Input: [1,3,5,6], 0
Output: 0
problem
 1 // 易错点:可能插入在最后,所以right不是length-1
 2 class Solution {
 3 public:
 4     int searchInsert(vector<int>& nums, int target) {
 5         int left = 0, right = nums.size();
 6         while (left < right) {
 7             int mid = (left + right)/2;
 8             if (nums[mid] == target)
 9                 return mid;
10             else if(nums[mid] < target)
11                 left = mid + 1;
12             else
13                 right = mid;
14         }
15         return left;
16     }
17 };
View Code

 


39. Combination Sum (medium)

 找到数组中所有和为target的组合,数可以重复使用,数组中无重复元素

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

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

Note:
All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.
For example, given candidate set [2, 3, 6, 7] and target 7, 
A solution set is: 
[
  [7],
  [2, 2, 3]
]
problem
 1 // 思路:backtracking
 2 class Solution {
 3 public:
 4     vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
 5         vector<vector<int>> res;
 6         vector<int> tmp;
 7         backtracking(candidates, res, tmp, target, 0);
 8         return res;
 9     }
10     void backtracking(vector<int>& candidates, vector<vector<int>>& res, vector<int> tmp, int target, int start) {
11         if (target == 0)
12             res.push_back(tmp);
13         if (target <= 0)
14             return;
15         for (int i = start; i < candidates.size(); ++i) {
16             tmp.push_back(candidates[i]);
17             backtracking(candidates, res, tmp, target - candidates[i], i);
18             tmp.pop_back();
19         }
20     }
21 };
View Code

 


40. Combination Sum II (medium)

找到数组中所有和为target的组合,每个数只能取一次,数组中有重复元素

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

Each number in C 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.
For example, given candidate set [10, 1, 2, 7, 6, 1, 5] and target 8, 
A solution set is: 
[
  [1, 7],
  [1, 2, 5],
  [2, 6],
  [1, 1, 6]
]
problem
 1 class Solution {
 2 public:
 3     vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
 4         sort(candidates.begin(), candidates.end());
 5         vector<vector<int>> res;
 6         vector<int> tmp;
 7         backtracking(candidates, res, tmp, target, 0);
 8         return res;
 9     }
10     void backtracking(vector<int>& candidates, vector<vector<int>>& res, vector<int>& tmp, int target, int start) {
11         if (target == 0)
12             res.push_back(tmp);
13         if (target <= 0)
14             return;
15         for (int i = start; i < candidates.size(); ++i) {
16             if (i > start && candidates[i] == candidates[i - 1])
17                 continue;
18             tmp.push_back(candidates[i]);
19             backtracking(candidates, res, tmp, target - candidates[i], i + 1);
20             tmp.pop_back();
21         }
22     }
23 };
View Code

 


41. First Missing Positive (hard) #

找到数组中第一个丢失的正整数

Given an unsorted integer array, find the first missing positive integer.

For example,
Given [1,2,0] return 3,
and [3,4,-1,1] return 2.

Your algorithm should run in O(n) time and uses constant space.
problem
 1 // 思路:把数字i放到i-1的位置上,再遍历
 2 // 易错点:1 判断数字是否大于边界;为了处理重复的数,如果位置上的数已经对了,就不用swap了
 3 //           2 如果全部满足,就返回最后的后一个
 4 class Solution {
 5 public:
 6     int firstMissingPositive(vector<int>& nums) {
 7         for (int i = 0; i < nums.size();) {
 8             if (nums[i] > 0 && nums[i] <= nums.size() && nums[i] != nums[nums[i] - 1])                                                //
 9                 swap(nums[i], nums[nums[i] - 1]);
10             else ++i;
11         }
12         for (int i = 0; i < nums.size(); ++i) {
13             if (nums[i] != i + 1)
14                 return i + 1;
15         }
16         return nums.size() + 1;                                    //
17     }
18 };
View Code

 


42. Trapping Rain Water (hard) #

水容量

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.

For example, 
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.
problem
 1 // 思路:两边到中间,记录左右两边边界
 2 class Solution {
 3 public:
 4     int trap(vector<int>& height) {
 5         int left = 0, right = height.size() - 1, height_left = 0, height_right = 0, res = 0;
 6         while (left <= right) {
 7             if (height[left] <= height[right]) {
 8                 if (height[left] < height_left)
 9                     res += height_left - height[left];
10                 else
11                     height_left = height[left];
12                 ++left;
13             }
14             else {
15                 if (height[right] < height_right)
16                     res += height_right - height[right];
17                 else
18                     height_right = height[right];
19                 --right;
20             }
21         }
22         return res;
23     }
24 };
View Code

 


45. Jump Game II (hard) #

跳步问题:数组中的数表示在当前位置可以跳跃的长度,计算从头到尾最少的跳跃步数

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.

For example:
Given array A = [2,3,1,1,4]

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.
problem
 1 // 思路:dfs,每走一步记录可以走的最远距离。
 2 class Solution {
 3 public:
 4     int jump(vector<int>& nums) {
 5         int pos_max = 0, pos_max_lst = 0, jumps = 0;
 6         for (int i = 0; i < nums.size() - 1; ++i) {
 7             pos_max = max(pos_max, i + nums[i]);
 8             if (pos_max >= nums.size() - 1)
 9                 return jumps + 1;
10             if (i == pos_max_lst) {
11                 pos_max_lst = pos_max;
12                 ++jumps;
13             }
14         }
15         return jumps;
16     }
17 };
View Code

 


48. Rotate Image (medium)

 旋转方阵

You are given an n x n 2D matrix representing an image.

Rotate the image by 90 degrees (clockwise).

Note:
You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation.

Example 1:

Given input matrix = 
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],

rotate the input matrix in-place such that it becomes:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]
Example 2:

Given input matrix =
[
  [ 5, 1, 9,11],
  [ 2, 4, 8,10],
  [13, 3, 6, 7],
  [15,14,12,16]
], 

rotate the input matrix in-place such that it becomes:
[
  [15,13, 2, 5],
  [14, 3, 4, 1],
  [12, 6, 8, 9],
  [16, 7,10,11]
]
problem
 1 // 思路:两次对称翻转,第一次按行翻转
 2 class Solution {
 3 public:
 4     void rotate(vector<vector<int>>& matrix) {
 5         reverse(matrix.begin(), matrix.end());
 6         for (int i = 0; i < matrix.size(); ++i) {
 7             for (int j = i + 1; j < matrix.size(); ++j)
 8                 swap(matrix[i][j], matrix[j][i]);
 9         }
10     }
11 };
View Code

 


53. Maximum Subarray (easy)

使数组中连续的数的和最大,返回和

Find the contiguous subarray within an array (containing at least one number) which has the largest sum.

For example, given the array [-2,1,-3,4,-1,2,1,-5,4],
the contiguous subarray [4,-1,2,1] has the largest sum = 6.
problem
 1 // 思路:计算累加;比较最大值;累加小于0则置零
 2 class Solution {
 3 public:
 4     int maxSubArray(vector<int>& nums) {
 5         int acc = 0, res = INT_MIN;
 6         for (int n : nums) {
 7             acc += n;
 8             res = max(res, acc);
 9             acc = max(0, acc);
10         }
11         return res;
12     }
13 };
View Code

 


54. Spiral Matrix (medium)

 以旋转的顺序将矩阵转换为数组

Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.

For example,
Given the following matrix:

[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]
You should return [1,2,3,6,9,8,7,4,5].
problem
 1 class Solution {
 2 public:
 3     vector<int> spiralOrder(vector<vector<int>>& matrix) {
 4         vector<int> res;
 5         if (matrix.size() == 0 || matrix[0].size() == 0) return res;
 6         int i = 0;
 7         int left = 0;
 8         int right = matrix[0].size() - 1;
 9         int up = 0;
10         int down = matrix.size() - 1;
11         while (up <= down && left <= right) {
12             for (i = left; i <= right; ++i)
13                 res.push_back(matrix[up][i]);
14             if (++up > down) break;                // @1
15             for (i = up; i <= down; ++i)
16                 res.push_back(matrix[i][right]);
17             if (--right < left) break;
18             for (i = right; i >= left; --i)
19                 res.push_back(matrix[down][i]);
20             if (--down < up) break;
21             for (i = down; i >= up; --i)
22                 res.push_back(matrix[i][left]);
23             if (++left > right) break;
24         }
25         return res;
26     }
27 };
View Code

 


55. Jump Game (medium)

跳步问题:数组中的数表示在当前位置可以跳跃的长度,判断是否能到达数组尾部

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.

For example:
A = [2,3,1,1,4], return true.

A = [3,2,1,0,4], return false.
problem
 1 class Solution {
 2 public:
 3     bool canJump(vector<int>& nums) {
 4         for (int i = 0, length = 0; i < nums.size(); ++i) {
 5             if (i > length) return false;
 6             length = max(length, nums[i] + i);
 7         }
 8         return true;
 9     }
10 };
View Code

 


56. Merge Intervals (medium)

 合并区间:把有重复的区间合并成一个

Given a collection of intervals, merge all overlapping intervals.

For example,
Given [1,3],[2,6],[8,10],[15,18],
return [1,6],[8,10],[15,18].
problem
 1 /**
 2  * Definition for an interval.
 3  * struct Interval {
 4  *     int start;
 5  *     int end;
 6  *     Interval() : start(0), end(0) {}
 7  *     Interval(int s, int e) : start(s), end(e) {}
 8  * };
 9  */
10 class Solution {
11 public:
12     vector<Interval> merge(vector<Interval>& intervals) {
13         vector<Interval> res;
14         sort(intervals.begin(), intervals.end(), [] (Interval a, Interval b) {return a.start < b.start;});
15         for (auto interval : intervals) {
16             if (res.empty() || interval.start > res.back().end)
17                 res.push_back(interval);
18             else
19                 res.back().end = max(interval.end, res.back().end);
20         }
21         return res;
22     }
23 };
View Code

 


57. Insert Interval (hard)

 在无重复的区间列表中插入一个区间,并合并重复的区间

Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).

You may assume that the intervals were initially sorted according to their start times.

Example 1:
Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9].

Example 2:
Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16].

This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10].
problem
 1 // 思路:分三段,中间的一段处理重复区间,可改变newInterval的值来简化代码
 2 class Solution {
 3 public:
 4     vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) {
 5         vector<Interval> res;
 6         int index = 0, length = intervals.size();
 7         for (; index < length && intervals[index].end < newInterval.start; ++index)
 8             res.push_back(intervals[index]);
 9         for (; index < length && intervals[index].start <= newInterval.end; ++index) {
10             newInterval.start = min(intervals[index].start, newInterval.start);
11             newInterval.end = max(intervals[index].end, newInterval.end);
12         }
13         res.push_back(newInterval);
14         for (; index < length; ++index)
15             res.push_back(intervals[index]);
16         return res;
17     }
18 };
View Code

 


59. Spiral Matrix II (medium)

以旋转的顺序将1~n*n填写到方阵中

Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order.

For example,
Given n = 3,

You should return the following matrix:
[
 [ 1, 2, 3 ],
 [ 8, 9, 4 ],
 [ 7, 6, 5 ]
]
problem
 1 class Solution {
 2 public:
 3     vector<vector<int>> generateMatrix(int n) {
 4         int i = -1, j = -1, m = 1;
 5         vector<vector<int>> res(n, vector<int>(n));
 6         while (m <= n*n) {
 7             for (++i, ++j; j < n - i; ++j)
 8                 res[i][j] = m++;
 9             for (++i, --j; i <= j; ++i)
10                 res[i][j] = m++;
11             for (--i, --j; j >= n - i - 1; --j)
12                 res[i][j] = m++;
13             for (++j, --i; i > j; --i)
14                 res[i][j] = m++;
15         }
16         return res;
17     }
18 };
View Code

 


62. Unique Paths (medium)

从(1, 1)到(m, n)的路径个数

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

How many possible unique paths are there?
problem
 1 class Solution {
 2 public:
 3     int uniquePaths(int m, int n) {
 4         vector<int> dp(m, 1);
 5         for (int i = 1; i < n; ++i) {
 6             for (int j = 1; j < m; ++j)
 7                 dp[j] = dp[j] + dp[j - 1];
 8         }
 9         return dp[m - 1];
10     }
11 };
View Code

 


63. Unique Paths II (medium)

 从(1, 1)到(m, n)的路径个数,给定矩阵中1代表不能通行

Follow up for "Unique Paths":

Now consider if some obstacles are added to the grids. How many unique paths would there be?

An obstacle and empty space is marked as 1 and 0 respectively in the grid.

For example,
There is one obstacle in the middle of a 3x3 grid as illustrated below.

[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]
The total number of unique paths is 2.

Note: m and n will be at most 100.
problem
 1 class Solution {
 2 public:
 3     int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
 4         int m = obstacleGrid.size(), n = obstacleGrid[0].size();
 5         vector<int> dp(n, 0);
 6         dp[0] = 1;
 7         for (int i = 0; i < m; ++i) {
 8             for (int j = 0; j < n; ++j) {
 9                 if (obstacleGrid[i][j] == 1)
10                     dp[j] = 0;
11                 else if (j > 0)
12                     dp[j] += dp[j - 1];
13             }
14         }
15         return dp[n - 1];
16     }
17 };
View Code

 


64. Minimum Path Sum (medium)

  从矩阵左上到右下,使路径上的和最小

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 1:
[[1,3,1],
 [1,5,1],
 [4,2,1]]
Given the above grid map, return 7. Because the path 13111 minimizes the sum.
problem
 1 class Solution {
 2 public:
 3     int minPathSum(vector<vector<int>>& grid) {
 4         int m = grid.size(), n = grid[0].size();
 5         vector<int> dp(n, INT_MAX);
 6         dp[0] = 0;
 7         for (int i = 0; i < m; ++i) {
 8             dp[0] += grid[i][0];
 9             for (int j = 1; j < n; ++j)
10                 dp[j] = min(dp[j], dp[j - 1]) + grid[i][j];
11         }
12         return dp[n - 1];
13     }
14 };
View Code

 


66. Plus One (easy)

用数组代表一个数,让这个数加一,返回数组

Given a non-negative integer represented as a non-empty array of digits, plus one to the integer.

You may assume the integer do not contain any leading zero, except the number 0 itself.

The digits are stored such that the most significant digit is at the head of the list.
problem
 1 class Solution {
 2 public:
 3     vector<int> plusOne(vector<int>& digits) {
 4         for (int i = digits.size() - 1; i >= 0; --i) {
 5             if (digits[i] == 9)
 6                 digits[i] = 0;
 7             else {
 8                 digits[i]++;
 9                 return digits;
10             }
11         }
12         digits[0] = 1;
13         digits.push_back(0);
14         return digits;
15     }
16 };
View Code

 


73. Set Matrix Zeroes (medium)

如果矩阵中有元素是0,就把同一行和同一列全置为0

Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in place.

Follow up:
Did you use extra space?
A straight forward solution using O(mn) space is probably a bad idea.
A simple improvement uses O(m + n) space, but still not the best solution.
Could you devise a constant space solution?
problem
 1 // 思路:把需要置0的行列存在第一行和第一列
 2 // 易错点:第二次遍历要从后往前
 3 class Solution {
 4 public:
 5     void setZeroes(vector<vector<int>>& matrix) {
 6         int m = matrix.size(), n = matrix[0].size();
 7         int col = 0;
 8         for (int i = 0; i < m; ++i) {
 9             if (matrix[i][0] == 0)
10                 col = 1;
11             for (int j = 1; j < n; ++j) {
12                 if (matrix[i][j] == 0) {
13                     matrix[i][0] = 0;
14                     matrix[0][j] = 0;
15                 }
16             }
17         }
18         for (int i = m - 1; i >= 0; --i) {
19             for (int j = n - 1; j > 0; --j) {
20                 if (matrix[i][0] == 0 || matrix[0][j] == 0)
21                     matrix[i][j] = 0;
22             }
23             if (col)
24                 matrix[i][0] = 0;
25         }
26     }
27 };
View Code

 


74. Search a 2D Matrix (medium)

在排好序的二维数组中查找target

Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:

Integers in each row are sorted from left to right.
The first integer of each row is greater than the last integer of the previous row.
For example,

Consider the following matrix:

[
  [1,   3,  5,  7],
  [10, 11, 16, 20],
  [23, 30, 34, 50]
]
Given target = 3, return true.
problem
 1 // 思路:当作一维的binary search,将坐标映射到二维。
 2 class Solution {
 3 public:
 4     bool searchMatrix(vector<vector<int>>& matrix, int target) {
 5         if (matrix.size() == 0)
 6             return false;
 7         int m = matrix.size(), n = matrix[0].size();
 8         int left = 0, right = m*n - 1;
 9         while (left <= right) {
10             int mid = (left + right)/2;
11             if (matrix[mid/n][mid%n] == target)
12                 return true;
13             else if (matrix[mid/n][mid%n] > target)
14                 right = mid - 1;
15             else
16                 left = mid + 1;
17         }
18         return false;
19     }
20 };
View Code

 


75. Sort Colors (medium)

数组中只有0,1,2;排序数组

Given an array with n objects colored red, white or blue, sort them 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.

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 an one-pass algorithm using only constant space?
problem
 1 class Solution {
 2 public:
 3     void sortColors(vector<int>& nums) {
 4         int left = 0, right = nums.size() - 1, i = 0;
 5         while (i <= right) {
 6             if (nums[i] == 0)
 7                 swap(nums[i++], nums[left++]);
 8             else if (nums[i] == 2)
 9                 swap(nums[i], nums[right--]);
10             else
11                 ++i;
12         }
13     }
14 };
View Code

 


78. Subsets (medium)

 无重复的数组的所有子集

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

Note: The solution set must not contain duplicate subsets.

For example,
If nums = [1,2,3], a solution is:

[
  [3],
  [1],
  [2],
  [1,2,3],
  [1,3],
  [2,3],
  [1,2],
  []
]
problem
 1 // backtracking
 2 class Solution {
 3 public:
 4     vector<vector<int>> subsets(vector<int>& nums) {
 5         vector<vector<int>> res;
 6         vector<int> tmp;
 7         subsets_recursive(res, tmp, nums, 0);
 8         return res;
 9     }
10     void subsets_recursive(vector<vector<int>>& res, vector<int>& tmp, vector<int>& nums, int start) {
11         res.push_back(tmp);
12         for (int i = start; i < nums.size(); ++i) {
13             tmp.push_back(nums[i]);
14             subsets_recursive(res, tmp, nums, i + 1);
15             tmp.pop_back();
16         }
17     }
18 };
View Code
 1 // 位操作:总共2^n个子集,第i个的元素的索引是,其二进制格式中值为1的位置索引
 2 class Solution {
 3 public:
 4     vector<vector<int>> subsets(vector<int>& nums) {
 5         int length = nums.size(), pow_len = pow(2, length);
 6         vector<vector<int>> res(pow_len);
 7         for (int i = 0; i < pow_len; ++i) {
 8             for (int j = 0; j < length; ++j) {
 9                 if ((i >> j) & 1)
10                     res[i].push_back(nums[j]);
11             }
12         }
13         return res;
14     }
15 };
View Code

 


79. Word Search (medium)

矩阵中找字符串

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.

For example,
Given board =

[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]
word = "ABCCED", -> returns true,
word = "SEE", -> returns true,
word = "ABCB", -> returns false.
problem
 1 // backtracking 存储已访问标记可在原地让元素取反
 2 class Solution {
 3 public:
 4     bool exist(vector<vector<char>>& board, string word) {
 5         if (board.size() == 0) return false;
 6         int m = board.size(), n = board[0].size();
 7         for (int i = 0; i < m; ++i) {
 8             for (int j = 0; j < n; ++j)
 9                 if (helper(board, word, i, j, 0)) return true;
10         }
11         return false;
12     }
13     bool helper(vector<vector<char>>& board, string& word, int i, int j, int start) {
14         if (start == word.size())
15             return true;
16         if (i < 0 || i >= board.size() || j < 0 || j >= board[0].size() || board[i][j] != word[start])
17             return false;
18         board[i][j] ^= 255;
19         bool res =  (helper(board, word, i - 1, j, start + 1) || \
20                      helper(board, word, i + 1, j, start + 1) || \
21                      helper(board, word, i, j - 1, start + 1) || \
22                      helper(board, word, i, j + 1, start + 1));
23         board[i][j] ^= 255;
24         return res;
25     }
26 };
View Code

 


80. Remove Duplicates from Sorted Array II (medium) #

删除重复的元素,使每个元素最多有两个

Follow up for "Remove Duplicates":
What if duplicates are allowed at most twice?

For example,
Given sorted array nums = [1,1,1,2,2,3],

Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 and 3. It doesn't matter what you leave beyond the new length.
problem
 1 // nums[i]不应和nums[i -2]比较,而是和nums[p - 2]
 2 class Solution {
 3 public:
 4     int removeDuplicates(vector<int>& nums) {
 5         int p = 0;
 6         for (int i = 0; i < nums.size(); ++i) {
 7             if (p < 2 || nums[i] != nums[p - 2])
 8                 nums[p++] = nums[i];
 9         }
10         return p;
11     }
12 };
View Code

 


81. Search in Rotated Sorted Array II (medium) #

在一个旋转后的有序数列中找到target,数列中有可能存在重复元素

Follow up for "Search in Rotated Sorted Array":
What if duplicates are allowed?

Would this affect the run-time complexity? How and why?
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Write a function to determine if a given target is in the array.

The array may contain duplicates.
problem
 1 // 思路:二分后判断哪一半是顺序的,再判断顺序的这一半是否存在target。如果都不是顺序的,必有一个与mid相等。
 2 class Solution {
 3 public:
 4     bool search(vector<int>& nums, int target) {
 5         int left = 0, right = nums.size() - 1;
 6         while (left <= right) {
 7             int mid = (left + right)/2;
 8             if (nums[mid] == target)
 9                 return true;
10             if (nums[mid] < nums[right]) {
11                 if (nums[mid] < target && nums[right] >= target)
12                     left = mid + 1;
13                 else
14                     right = mid - 1;
15             }
16             else if (nums[mid] > nums[left]) {
17                 if (nums[mid] > target && nums[left] <= target)
18                     right = mid - 1;
19                 else
20                     left = mid + 1;
21             }
22             else if (nums[mid] == nums[right])
23                 --right;
24             else if (nums[mid] == nums[left])
25                 ++left;
26         }
27         return false;
28     }
29 };
View Code

 


84. Largest Rectangle in Histogram (hard) #

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.

For example,
Given heights = [2,1,5,6,2,3],
return 10.
problem
 1 // 思路:遍历每一个高度,当后面一个比当前高就入栈,没有就出栈,计算面积。
 2 // 易错点:1 为了处理最后一个元素,可将原数组补零;2 heights[tmp.back()]写成tmp.back();3 漏掉
 3 class Solution {
 4 public:
 5     int largestRectangleArea(vector<int>& heights) {
 6         int res = 0;
 7         vector<int> tmp;
 8         heights.push_back(0);                               // @1
 9         for (int i = 0; i <= heights.size(); ++i) {
10             if (tmp.size() == 0 || heights[tmp.back()] < heights[i])   // @2
11                 tmp.push_back(i);
12             else {
13                 while ((!tmp.empty()) && heights[tmp.back()] > heights[i]) {
14                     int height = heights[tmp.back()];
15                     tmp.pop_back();
16                     int width = tmp.empty() ? i : i - tmp.back() - 1;
17                     res = max(res, height*width);
18                 }
19                 tmp.push_back(i);             // @3
20             }
21         }
22         return res;
23     }
24 };
View Code

 


85. Maximal Rectangle (hard) #

 找到矩阵中,最大的 值全为1的子矩阵

Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.

For example, given the following matrix:

1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Return 6.
problem
 1 // 思路:从上往下遍历每一行,计算第0到row行的result:对于某一行,第i个元素的高度作为矩阵的高,计算矩阵的长。
 2 class Solution {
 3 public:
 4     int maximalRectangle(vector<vector<char>>& matrix) {
 5         if (matrix.empty()) return 0;
 6         int m = matrix.size(), n = matrix[0].size(), res = 0;
 7         vector<int> left(n, 0), right(n, n), height(n, 0);
 8         for (int row = 0; row < m; ++row) {
 9             int cur_left = 0, cur_right = n;
10             for (int i = 0; i < n; ++i) {
11                 if (matrix[row][i] == '1') {
12                     ++height[i];
13                     left[i] = max(left[i], cur_left);
14                 }
15                 else {
16                     height[i] = 0;
17                     left[i] = 0;
18                     cur_left = i + 1;
19                 }
20             }
21             for (int i = n - 1; i >= 0; --i) {
22                 if (matrix[row][i] == '1')
23                     right[i] = min(right[i], cur_right);
24                 else {
25                     right[i] = n;
26                     cur_right = i;
27                 }
28             }
29             for (int i = 0; i < n; ++i)
30                 res = max(res, height[i]*(right[i] - left[i]));
31         }
32         return res;
33     }
34 };
View Code
 1 // 思路:使用84. Largest Rectangle in Histogram的方法计算每一行
 2 class Solution {
 3 public:
 4     int maximalRectangle(vector<vector<char>>& matrix) {
 5         if (matrix.empty()) return 0;
 6         int m = matrix.size(), n = matrix[0].size(), res = 0;
 7         vector<int> height(n + 1, 0);
 8         for (int i = 0; i < m; ++i) {
 9             vector<int> stack;
10             for (int j = 0; j < n + 1; ++j) {
11                 if (j < n && matrix[i][j] == '1')
12                     height[j]++;
13                 else
14                     height[j] = 0;
15                 if (stack.empty() || height[stack.back()] <= height[j])
16                     stack.push_back(j);
17                 else {
18                     while (!stack.empty() && height[stack.back()] >= height[j]) {
19                         int h_index = stack.back();
20                         stack.pop_back();
21                         int width = stack.empty() ? j : j - stack.back() - 1;
22                         res = max(res, height[h_index]*width);
23                     }
24                     stack.push_back(j);
25                 }
26             }
27         }
28         return res;
29     }
30 };
View Code

 


88. Merge Sorted Array (easy)

合并排好序的数列

Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.

Note:
You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively.
probelm
 1 class Solution {
 2 public:
 3     void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
 4         --m; --n;
 5         for (int i = m + n + 1; i >= 0; --i) {
 6             if (m < 0 || (n>=0 && nums1[m] < nums2[n]))
 7                 nums1[i] = nums2[n--];
 8             else
 9                 nums1[i] = nums1[m--];
10         }
11     }
12 };
View Code

 


90. Subsets II (medium)

有重复元素的数组的子集

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.

For example,
If nums = [1,2,2], a solution is:

[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]
problem
 1 class Solution {
 2 public:
 3     vector<vector<int>> subsetsWithDup(vector<int>& nums) {
 4         vector<vector<int>> res;
 5         vector<int> tmp;
 6         sort(nums.begin(), nums.end());
 7         backtracking(res, tmp, nums, 0);
 8         return res;
 9     }
10     void backtracking(vector<vector<int>>& res, vector<int>& tmp, vector<int>& nums, int start) {
11         res.push_back(tmp);
12         if (start == nums.size()) return;
13         for (int i = start; i < nums.size(); ++i) {
14             if (i > start && nums[i] == nums[i - 1]) continue;
15             tmp.push_back(nums[i]);
16             backtracking(res, tmp, nums, i + 1);
17             tmp.pop_back();
18         }
19     }
20 };
View Code
 1 // 在res中的元素上添加新的值
 2 class Solution {
 3 public:
 4     vector<vector<int>> subsetsWithDup(vector<int>& nums) {
 5         vector<vector<int>> res = {{}};
 6         sort(nums.begin(), nums.end());
 7         for (int i = 0; i < nums.size();) {
 8             int res_size = res.size(), count = 1;
 9             while (i + count < nums.size() && nums[i] == nums[i +count])
10                 ++count;
11             for (int j = 0; j < res_size; ++j) {
12                 vector<int> tmp = res[j];
13                 for (int c = count; c > 0; --c) {
14                     tmp.push_back(nums[i]);
15                     res.push_back(tmp);
16                 }
17             }
18             i += count;
19         }
20         return res;
21     }
22 };
View Code
 1 // 没有重复时,遍历上次的结果,有重复时,遍历上次新加入的结果
 2 class Solution {
 3 public:
 4     vector<vector<int>> subsetsWithDup(vector<int>& nums) {
 5         vector<vector<int>> res = {{}};
 6         sort(nums.begin(), nums.end());
 7         int start = 0, res_size = 0;
 8         for (int i = 0; i < nums.size(); i += 1) {
 9             start = (i > 0 && nums[i] == nums[i - 1]) ? res_size : 0;
10             res_size = res.size();
11             for (int j = start; j < res_size; ++j) {
12                 vector<int> tmp = res[j];
13                 tmp.push_back(nums[i]);
14                 res.push_back(tmp);
15             }
16         }
17         return res;
18     }
19 };
View Code

 


105. Construct Binary Tree from Preorder and Inorder Traversal (medium)

 通过二叉树的前序遍历和中序遍历,还原二叉树

Given preorder and inorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.
problem
 1 // 思路:递归:前序的第一个是根节点,通过根节点找到中序的index,则index左的元素都在左节点。
 2 class Solution {
 3 public:
 4     TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
 5         int index = 0;
 6         return helper(preorder, inorder, 0, preorder.size() - 1, index);
 7     }
 8     TreeNode* helper(vector<int>& preorder, vector<int>& inorder, int left, int right, int& index) {
 9         if (left > right)
10             return NULL;
11         int root_val = preorder[index++], root_index;
12         TreeNode* root = new TreeNode(root_val);
13         for (root_index = left; root_index <= right && inorder[root_index] != root_val; ++root_index);
14         root -> left = helper(preorder, inorder, left, root_index - 1, index);
15         root -> right = helper(preorder, inorder, root_index + 1, right, index);
16         return root;
17     }
18 };
View Code
 1 // 迭代:以前序遍历为主,加左节点,入栈,遇到中序的值就出栈,加右节点
 2 class Solution {
 3 public:
 4     TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) {
 5         if (preorder.size() == 0)
 6             return NULL;
 7         stack<TreeNode*> st;
 8         int i = 0, p = 1, l_r = 0;
 9         TreeNode* root = new TreeNode(preorder[0]), *node = root;
10         st.push(node);
11         while (i < inorder.size()) {
12             if (!st.empty() && st.top() -> val == inorder[i]) {
13                 node = st.top();
14                 st.pop();
15                 l_r = 1;
16                 ++i;
17             }
18             else {
19                 if (l_r == 0) {
20                     node -> left = new TreeNode(preorder[p++]);
21                     node = node -> left;
22                 }
23                 else {
24                     node -> right = new TreeNode(preorder[p++]);
25                     node = node -> right;
26                 }
27                 st.push(node);
28                 l_r = 0;                    // @1
29             }
30         }
31         return root;
32     }
33 };
View Code

 


106. Construct Binary Tree from Inorder and Postorder Traversal (medium)

  通过二叉树的后序遍历和中序遍历,还原二叉树

Given inorder and postorder traversal of a tree, construct the binary tree.

Note:
You may assume that duplicates do not exist in the tree.
problem
 1 class Solution {
 2 public:
 3     TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) {
 4         int tail = postorder.size() - 1;
 5         return func(postorder, inorder, tail, 0, tail);
 6     }
 7     TreeNode* func(vector<int>& postorder, vector<int>& inorder, int& tail, int left, int right) {
 8         if (left > right) return NULL;
 9         int head_index;
10         int head_val = postorder[tail--];
11         for (int i = left; i <= right; ++i) {
12             if (inorder[i] == head_val) head_index = i;
13         }
14         TreeNode* root = new TreeNode(head_val);                  // @1
15         root -> right = func(postorder, inorder, tail, head_index + 1, right);     // @2
16         root -> left = func(postorder, inorder, tail, left, head_index - 1);       // @2
17         return root;
18     }
19 };
View Code

 


118. Pascal's Triangle (easy)

杨辉三角

Given numRows, generate the first numRows of Pascal's triangle.

For example, given numRows = 5,
Return

[
     [1],
    [1,1],
   [1,2,1],
  [1,3,3,1],
 [1,4,6,4,1]
]
problem
 1 class Solution {
 2 public:
 3     vector<vector<int>> generate(int numRows) {
 4         vector<vector<int>> res(numRows);
 5         for (int i = 0; i < numRows; ++i) {
 6             res[i].push_back(1);
 7             for (int j = 1; j < i; ++j)
 8                 res[i].push_back(res[i - 1][j - 1] + res[i - 1][j]);
 9             if (i > 0) res[i].push_back(1);
10         }
11         return res;
12     }
13 };
View Code

 


119. Pascal's Triangle II (easy)

杨辉三角的第k行

Given an index k, return the kth row of the Pascal's triangle.

For example, given k = 3,
Return [1,3,3,1].

Note:
Could you optimize your algorithm to use only O(k) extra space?
problem
 1 class Solution {
 2 public:
 3     vector<int> getRow(int rowIndex) {
 4         vector<int> res;
 5         for (int i = 0; i <= rowIndex; ++i) {
 6             res.push_back(1);
 7             for (int j = i - 1; j > 0; --j)
 8                 res[j] += res[j - 1];
 9         }
10         return res;
11     }
12 };
View Code

 


120. Triangle (medium)

Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.

For example, given the following triangle
[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]
The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).

Note:
Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.
problem
 1 // 从最后一行往前计算,最后得到第一行的一个值就是结果
 2 class Solution {
 3 public:
 4     int minimumTotal(vector<vector<int>>& triangle) {
 5         vector<int> res(triangle.back());
 6         for (int i = triangle.size() - 2; i >= 0; --i) {
 7             for (int j = 0; j <= i + 1; ++j)
 8                 res[j] = min(res[j], res[j + 1]) + triangle[i][j];
 9         }
10         return res[0];
11     }
12 };
View Code
 1 // 从上往下,最后计算最后一行的最小值 (较差的算法)
 2 class Solution {
 3 public:
 4     int minimumTotal(vector<vector<int>>& triangle) {
 5         if (triangle.size() == 0) return 0;
 6         vector<int> res(triangle.size(), triangle[0][0]);
 7         for (int i = 1; i < triangle.size(); ++i) {
 8             res[i] = triangle[i][i] + res[i - 1];
 9             for (int j = i - 1; j > 0; --j) {
10                 res[j] = triangle[i][j] + min(res[j], res[j - 1]);
11             }
12             res[0] = triangle[i][0] + res[0];
13         }
14         return *min_element(res.begin(), res.end());
15     }
16 };
View Code

 


121. Best Time to Buy and Sell Stock (easy)

股票的最好买入卖出时间,返回最大收益

Say you have an array for which the ith element is the price of a given stock on day i.

If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.

Example 1:
Input: [7, 1, 5, 3, 6, 4]
Output: 5

max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price)
Example 2:
Input: [7, 6, 4, 3, 1]
Output: 0

In this case, no transaction is done, i.e. max profit = 0.
problem
 1 class Solution {
 2 public:
 3     int maxProfit(vector<int>& prices) {
 4         int low = INT_MAX, res = 0;
 5         for (auto p : prices) {
 6             low = min(low, p);
 7             res = max(res, p - low);
 8         }
 9         return res;
10     }
11 };
View Code
 1 // Kadane's Algorithm
 2 // 把相邻数字的差最为涨幅,就相当于求最大子数组和问题
 3 class Solution {
 4 public:
 5     int maxProfit(vector<int>& prices) {
 6         int res = 0, maxSoFar = 0; 
 7         for (int i = 1; i < prices.size(); ++i) {
 8             maxSoFar = max(0, maxSoFar + prices[i] - prices[i - 1]);
 9             res = max(res, maxSoFar);
10         }
11         return res;
12     }
13 };
View Code

 


122. Best Time to Buy and Sell Stock II (easy)

股票的最好买入卖出时间,返回最大收益,可进行多次交易

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
problem
 1 // 思路:Kadane's Algorithm
 2 class Solution {
 3 public:
 4     int maxProfit(vector<int>& prices) {
 5         int res = 0;
 6         for (int i = 1; i < prices.size(); ++i)
 7             res += max(0, prices[i] - prices[i - 1]);
 8         return res;
 9     }
10 };
View Code

 


123. Best Time to Buy and Sell Stock III (hard)

股票的最好买入卖出时间,返回最大收益,最多进行两次交易

Say you have an array for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete at most two transactions.

Note:
You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).
problem
 1 // 动态规划,可拓展到times次交易。
 2 class Solution {
 3 public:
 4     int maxProfit(vector<int>& prices) {
 5         if (prices.size() < 2) return 0;
 6         int cur, length = prices.size(), times = 2;
 7         vector<vector<int>> profit(times + 1, vector<int>(length, 0));
 8         for (int row = 1; row <= times; ++row) {
 9             cur = -prices[0];
10             for (int i = 1; i < length; ++i) {
11                 profit[row][i] = max(profit[row][i - 1], cur + prices[i]);
12                 cur = max(cur, profit[row - 1][i - 1] - prices[i]);
13             }
14         }
15         return profit[times][length - 1];
16     }
17 };
View Code
 1 // a cleaner solution
 2 class Solution {
 3 public:
 4     int maxProfit(vector<int> &prices) {
 5         // f[k, ii] represents the max profit up until prices[ii] (Note: NOT ending with prices[ii]) using at most k transactions. 
 6         // f[k, ii] = max(f[k, ii-1], prices[ii] - prices[jj] + f[k-1, jj]) { jj in range of [0, ii-1] }
 7         //          = max(f[k, ii-1], prices[ii] + max(f[k-1, jj] - prices[jj]))
 8         // f[0, ii] = 0; 0 times transation makes 0 profit
 9         // f[k, 0] = 0; if there is only one price data point you can't make any money no matter how many times you can trade
10         if (prices.size() <= 1) return 0;
11         else {
12             int K = 2; // number of max transation allowed
13             int maxProf = 0;
14             vector<vector<int>> f(K+1, vector<int>(prices.size(), 0));
15             for (int kk = 1; kk <= K; kk++) {
16                 int tmpMax = f[kk-1][0] - prices[0];
17                 for (int ii = 1; ii < prices.size(); ii++) {
18                     f[kk][ii] = max(f[kk][ii-1], prices[ii] + tmpMax);
19                     tmpMax = max(tmpMax, f[kk-1][ii] - prices[ii]);
20                     maxProf = max(f[kk][ii], maxProf);
21                 }
22             }
23             return maxProf;
24         }
25     }
26 };
View Code

 


126. Word Ladder II (hard)

单词接龙,前后单词只有一个字母不同

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord, such that:

Only one letter can be changed at a time
Each transformed word must exist in the word list. Note that beginWord is not a transformed word.
For example,

Given:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log","cog"]
Return
  [
    ["hit","hot","dot","dog","cog"],
    ["hit","hot","lot","log","cog"]
  ]
Note:
Return an empty list if there is no such transformation sequence.
All words have the same length.
All words contain only lowercase alphabetic characters.
You may assume no duplicates in the word list.
You may assume beginWord and endWord are non-empty and are not the same.
UPDATE (2017/1/20):
The wordList parameter had been changed to a list of strings (instead of a set of strings). Please reload the code definition to get the latest changes.
problem
 1 // 待重写
 2 // 思路:把所有wordList写入字典,然后从beginWord开始进行BFS,字典记录搜索到当前word的步数,以防止重复使用;再用一个字典记录能到达当前word的所有前一个word。最后从后往前利用第二个字典往回遍历。
 3 class Solution {
 4 public:
 5     vector<vector<string>> findLadders(string beginWord, string endWord, vector<string>& wordList) {
 6         int step = 0, min_step = INT_MAX;
 7         unordered_map<string, int> map;
 8         unordered_map<string, vector<string>> back_map;
 9         vector<vector<string>> res;
10         queue<string> q;
11         for (string word : wordList)
12             map[word] = INT_MAX;
13         map[beginWord] = 0;
14         q.push(beginWord);
15         while (!q.empty()) {
16             string cur = q.front();
17             step = map[cur] + 1;                         // trick
18             if (step > min_step) break;
19             for (int i = 0; i < cur.size(); ++i) {
20                 char tmp = cur[i];
21                 for (char c = 'a'; c < 'z'; ++c) {
22                     cur[i] = c;
23                     if (c == tmp || map.find(cur) == map.end()) continue;
24                     if (cur == endWord) {
25                         min_step = step;
26                         back_map[endWord].push_back(q.front());
27                         i = cur.size() - 1;
28                         break;
29                     }
30                     if (map[cur] >= step) {
31                         if (map[cur] == INT_MAX) {
32                             q.push(cur);
33                             map[cur] = step;
34                         }
35                         back_map[cur].push_back(q.front());
36                     }
37                 }
38                 cur[i] = tmp;
39             }
40             q.pop();
41         }
42         if (min_step == INT_MAX) return res;
43         vector<string> path(min_step + 1);
44         path[0] = beginWord;
45         go_back(res, back_map, path, endWord, beginWord, min_step);
46         return res;
47     }
48     void go_back(vector<vector<string>>& res, unordered_map<string, vector<string>>& back_map, vector<string>& path, string endWord, string beginWord, int step) {
49         if (step == 0) {
50             res.push_back(path);
51             return;
52         }
53         path[step] = endWord;
54         for (auto next_end : back_map[endWord])
55             go_back(res, back_map, path, next_end, beginWord, step - 1);
56     }
57 };
View Code

 


128. Longest Consecutive Sequence (hard) #

最长的连续序列:找到数组中可以组成的连续数字的最长长度

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

For example,
Given [100, 4, 200, 1, 3, 2],
The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4.

Your algorithm should run in O(n) complexity.
problem
 1 class Solution {
 2 public:
 3     int longestConsecutive(vector<int>& nums) {
 4         unordered_map<int, int> map;
 5         int res = 0;
 6         for (int n : nums) {
 7             if (map[n] > 0) continue;
 8             int left = map[n - 1];
 9             int right = map[n + 1];
10             map[n] = left + right + 1;
11             map[n - left] = map[n];
12             map[n + right] = map[n];
13             res = max(res, map[n]);
14         }
15         return res;
16     }
17 };
View Code

 


152. Maximum Product Subarray (medium) #

拥有最大乘积的子序列

Find the contiguous subarray within an array (containing at least one number) which has the largest product.

For example, given the array [2,3,-2,4],
the contiguous subarray [2,3] has the largest product = 6.
problem
 1 // 思路:存储以nums[i]结尾的子序列中最大的乘积和最小的乘积
 2 class Solution {
 3 public:
 4     int maxProduct(vector<int>& nums) {
 5         int max_val = nums[0], min_val = nums[0], res = nums[0];
 6         for (int i = 1; i < nums.size(); ++i) {
 7             if (nums[i] < 0)
 8                 swap(min_val, max_val);
 9             min_val = min(min_val*nums[i], nums[i]);
10             max_val = max(max_val*nums[i], nums[i]);
11             res = max(res, max_val);
12         }
13         return res;
14     }
15 };
View Code

 


153. Find Minimum in Rotated Sorted Array (medium)

在旋转后的有序数列中找到最小值

Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Find the minimum element.

You may assume no duplicate exists in the array.
problem
 1 class Solution {
 2 public:
 3     int findMin(vector<int>& nums) {
 4         int left = 0, right = nums.size() - 1;
 5         while (left <= right) {
 6             int mid = (left + right)/2;
 7             if (nums[mid] < nums[left])
 8                 right = mid;
 9             else if (nums[mid] > nums[right])
10                 left = mid + 1;
11             else
12                 return nums[left];
13         }
14         return nums[left];
15     }
16 };
View Code

 


154. Find Minimum in Rotated Sorted Array II (hard)

在旋转后的有序数列中找到最小值,,数组中可能有重复的数

Follow up for "Find Minimum in Rotated Sorted Array":
What if duplicates are allowed?

Would this affect the run-time complexity? How and why?
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

Find the minimum element.

The array may contain duplicates.
problem
 1 class Solution {
 2 public:
 3     int findMin(vector<int>& nums) {
 4         int left = 0, right = nums.size() - 1;
 5         while (left < right) {
 6             int mid = (left + right)/2;
 7             if (nums[left] > nums[mid])
 8                 right = mid;
 9             else if (nums[mid] > nums[right])
10                 left = mid + 1;
11             else
12                 --right;
13         }
14         return nums[left];
15     }
16 };
View Code

 


162. Find Peak Element (medium)

找一个峰值,只要大于两边的数就可以,nums[-1]=nums[n]=负无穷

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

Given an input array where num[i] ≠ num[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 num[-1] = num[n] = -∞.

For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2.
problem
 1 // O(lgn)
 2 class Solution {
 3 public:
 4     int findPeakElement(vector<int>& nums) {
 5         int left = 0, right = nums.size() - 1;
 6         while (left < right) {
 7             int mid = (left + right)/2;
 8             if (nums[mid] < nums[mid + 1])
 9                 left = mid + 1;
10             else
11                 right = mid;
12         }
13         return left;
14     }
15 };
View Code
 1 // O(n)
 2 class Solution {
 3 public:
 4     int findPeakElement(const vector<int> &num) {
 5         for(int i = 1; i < num.size(); i ++)
 6         {
 7             if(num[i] < num[i-1])
 8                 return i-1;
 9         }
10         return num.size()-1;
11     }
12 };
View Code

 


167. Two Sum II - Input array is sorted (easy)

 有序数组中找到和为target的两个数的索引(结果只有一组)

Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number.

The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.

You may assume that each input would have exactly one solution and you may not use the same element twice.

Input: numbers={2, 7, 11, 15}, target=9
Output: index1=1, index2=2
problem
 1 class Solution {
 2 public:
 3     vector<int> twoSum(vector<int>& numbers, int target) {
 4         int left = 0, right = numbers.size() - 1;
 5         while (left < right) {
 6             if (numbers[left] + numbers[right] == target)
 7                 return vector<int>{left + 1, right + 1};
 8             else if (numbers[left] + numbers[right] < target)
 9                 ++left;
10             else
11                 --right;
12         }
13         return vector<int>();
14     }
15 };
View Code

 


169. Majority Element (easy)

 找到出现次数大于n/2的元素

Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

You may assume that the array is non-empty and the majority element always exist in the array.
problem
 1 class Solution {
 2 public:
 3     int majorityElement(vector<int>& nums) {
 4         int major = 0, times = 0;
 5         for (int n : nums) {
 6             if (times < 1) {
 7                 major = n;
 8                 ++times;
 9             }
10             else if (n == major)
11                 ++times;
12             else
13                 --times;
14         }
15         return major;
16     }
17 };
View Code

 


189. Rotate Array (easy)

 旋转数组,使最后的k个数旋转到最前面

Rotate an array of n elements to the right by k steps.

For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to [5,6,7,1,2,3,4].

Note:
Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.
problem
1 class Solution {
2 public:
3     void rotate(vector<int>& nums, int k) {
4         k %= nums.size();
5         reverse(nums.begin(), nums.end());
6         reverse(nums.begin(), nums.begin() + k);
7         reverse(nums.begin() + k, nums.end());
8     }
9 };
View Code

 


209. Minimum Size Subarray Sum (medium)

最短的连续数组,使和大于s

Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead.

For example, given the array [2,3,1,2,4,3] and s = 7,
the subarray [4,3] has the minimal length under the problem constraint.
problem
 1 class Solution {
 2 public:
 3     int minSubArrayLen(int s, vector<int>& nums) {
 4         int res = INT_MAX, left = 0, right = 0, sum = 0, length = 0;
 5         while (right < nums.size()) {
 6             sum += nums[right++];
 7             while (sum >= s) {
 8                 res = min(res, right - left);
 9                 sum -= nums[left++];
10             }
11         }
12         return res == INT_MAX ? 0 : res;
13     }
14 };
View Code

 


216. Combination Sum III (medium)

在1到9中找到和为n的k个数,不能重复

Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers.


Example 1:

Input: k = 3, n = 7

Output:

[[1,2,4]]

Example 2:

Input: k = 3, n = 9

Output:

[[1,2,6], [1,3,5], [2,3,4]]
problem
 1 class Solution {
 2 public:
 3     vector<vector<int>> combinationSum3(int k, int n) {
 4         vector<vector<int>> res;
 5         vector<int> tmp(k);
 6         backtracking(res, tmp, 0, k, 1, 9, n);
 7         return res;
 8     }
 9     void backtracking(vector<vector<int>>& res, vector<int>& tmp, int index, int k, int start, int end, int sum) {
10         if (k == index) {
11             if (sum == 0)
12                 res.push_back(tmp);
13             return;
14         }
15         for (int i = start; i <= end; ++i) {
16             tmp[index] = i;
17             if (sum - i < 0) break;
18             backtracking(res, tmp, index + 1, k, i + 1, end, sum - i);
19         }
20     }
21 };
View Code

 


217. Contains Duplicate (easy)

判断是否包含重复元素

Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.
problem
 1 class Solution {
 2 public:
 3     bool containsDuplicate(vector<int>& nums) {
 4         unordered_map<int, int> count_map;
 5         for (int num : nums) {
 6             if (++count_map[num] > 1)
 7                 return true;
 8         }
 9         return false;
10     }
11 };
View Code

 


219. Contains Duplicate II (easy)

判断距离k以内的元素中是否包含重复元素

Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k.
problem
 1 class Solution {
 2 public:
 3     bool containsNearbyDuplicate(vector<int>& nums, int k) {
 4        unordered_set<int> s;
 5         for (int i = 0; i < nums.size(); ++i) {
 6             if (i > k)
 7                 s.erase(nums[i - k - 1]);
 8             if (!s.insert(nums[i]).second)
 9                 return true;
10         }
11         return false;
12     }
13 };
View Code

 


228. Summary Ranges (medium)

给出有序数组,罗列数组的范围

Given a sorted integer array without duplicates, return the summary of its ranges.

Example 1:
Input: [0,1,2,4,5,7]
Output: ["0->2","4->5","7"]
Example 2:
Input: [0,2,3,4,6,8,9]
Output: ["0","2->4","6","8->9"]
problem
 1 class Solution {
 2 public:
 3     vector<string> summaryRanges(vector<int>& nums) {
 4         vector<string> res;
 5         if (nums.empty())
 6             return res;
 7         int last = 0, right;
 8         for (int i = 1; i <= nums.size(); ++i) {
 9             if (i == nums.size() || nums[i] != nums[i - 1] + 1) {
10                 if (i - last == 1)
11                     res.push_back(to_string(nums[last]));
12                 else
13                     res.push_back(to_string(nums[last]) + "->" + to_string(nums[i - 1]));
14                 last = i;
15             }
16         }
17         return res;
18     }
19 };
View Code

 


229. Majority Element II (medium) #

找到出现次数大于1/3总数的数字

Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space.
problem
 1 // 思路:先找到出现次数最多的两个数,再看是否大于1/3
 2 class Solution {
 3 public:
 4     vector<int> majorityElement(vector<int>& nums) {
 5         vector<int> res;
 6         int num1 = 0, num2 = 0, count1 = 0, count2 = 0;
 7         for (int n : nums) {
 8             if (n == num1)
 9                 ++count1;
10             else if (n == num2)
11                 ++count2;
12             else if (count1 == 0) {
13                 num1 = n;
14                 count1 = 1;
15             }
16             else if (count2 == 0) {
17                 num2 = n;
18                 count2 = 1;
19             }
20             else {
21                 --count1;
22                 --count2;
23             }
24         }
25         count1 = count2 = 0;
26         for (int n : nums) {
27             if (n == num1)
28                 ++count1;
29             else if (n == num2)
30                 ++count2;
31         }
32         if (count1 > nums.size()/3)
33             res.push_back(num1);
34         if (count2 > nums.size()/3)
35             res.push_back(num2);
36         return res;
37     }
38 };
View Code

 


238. Product of Array Except Self (medium) #

 计算除本身之外所有数的乘积

Given an array of n integers where n > 1, nums, return an array output such that output[i] is equal to the product of all the elements of nums except nums[i].

Solve it without division and in O(n).

For example, given [1,2,3,4], return [24,12,8,6].

Follow up:
Could you solve it with constant space complexity? (Note: The output array does not count as extra space for the purpose of space complexity analysis.)
problem
 1 class Solution {
 2 public:
 3     vector<int> productExceptSelf(vector<int>& nums) {
 4         vector<int> res(nums.size());
 5         res[0] = 1;
 6         for (int i = 1; i < nums.size(); ++i)
 7             res[i] = res[i - 1]*nums[i - 1];
 8         int tmp = 1;
 9         for (int i = nums.size() - 1; i > 0; --i) {
10             tmp *= nums[i];
11             res[i - 1] *= tmp;
12         }
13         return res;
14     }
15 };
View Code

 


268. Missing Number (easy) #

找到0到n中,丢失的数

Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is missing from the array.

Example 1

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

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

Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?
problem
 1 class Solution {
 2 public:
 3     int missingNumber(vector<int>& nums) {
 4         int res = nums.size();
 5         for (int i = 0; i < nums.size(); ++i) {
 6             res ^= i;
 7             res ^= nums[i];
 8         }
 9         return res;
10     }
11 };
View Code

 


283. Move Zeroes (easy)

 把0移到数组右边

Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements.

For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].

Note:
You must do this in-place without making a copy of the array.
Minimize the total number of operations.
problem
 1 class Solution {
 2 public:
 3     void moveZeroes(vector<int>& nums) {
 4         int pre = 0;
 5         for (int i = 0; i < nums.size(); ++i) {
 6             if (nums[i] != 0)
 7                 nums[pre++] = nums[i];
 8         }
 9         while (pre < nums.size())
10             nums[pre++] = 0;
11     }
12 };
View Code

 


287. Find the Duplicate Number (medium) #

找到有重复的元素:数字范围是1-n,重复次数>=2

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.

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.
problem
 1 // 思路:由于索引是0-n,数字是1-n,把数组看成链表,则索引0可作为you'huan有环链表的入口
 2 class Solution {
 3 public:
 4     int findDuplicate(vector<int>& nums) {
 5         int slow = nums[0];
 6         int fast = nums[nums[0]];
 7         while (slow != fast) {
 8             slow = nums[slow];
 9             fast = nums[nums[fast]];
10         }
11         fast = 0;
12         while (fast != slow) {
13             fast = nums[fast];
14             slow = nums[slow];
15         }
16         return slow;
17     }
18 };
View Code

 


289. Game of Life (medium) #

存活游戏

According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970."

Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article):

Any live cell with fewer than two live neighbors dies, as if caused by under-population.
Any live cell with two or three live neighbors lives on to the next generation.
Any live cell with more than three live neighbors dies, as if by over-population..
Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.
Write a function to compute the next state (after one update) of the board given its current state.

Follow up: 
Could you solve it in-place? Remember that the board needs to be updated at the same time: You cannot update some cells first and then use their updated values to update other cells.
In this question, we represent the board using a 2D array. In principle, the board is infinite, which would cause problems when the active area encroaches the border of the array. How would you address these problems?
problem
 1 class Solution {
 2 public:
 3     void gameOfLife(vector<vector<int>>& board) {
 4         int size1 = board.size(), size2 = size1 ? board[0].size() : 0;
 5         for (int i = 0; i < size1; ++i) {
 6             for (int j = 0; j < size2; ++j) {
 7                 int count = 0;
 8                 for (int m = max(0, i - 1); m < min(i + 2, size1); ++m) {
 9                     for (int n = max(0, j - 1); n < min(j + 2, size2); ++n) {
10                         count += board[m][n]&1;
11                     }
12                 }
13                 if (count == 3 || count - board[i][j] == 3)
14                     board[i][j] |= 2;
15             }
16         }
17         for (int i = 0; i < size1; ++i) {
18             for (int j = 0; j < size2; ++j) {
19                 board[i][j] >>= 1;
20             }
21         }
22     }
23 };
View Code

 


380. Insert Delete GetRandom O(1) (medium)

实现一个存、取、删随机数的类

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

insert(val): Inserts an item val to the set if not already present.
remove(val): Removes an item val from the set if present.
getRandom: Returns a random element from current set of elements. 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();
problem
 1 // 用vector存数,用map存索引
 2 class RandomizedSet {
 3 public:
 4     /** Initialize your data structure here. */
 5     RandomizedSet() {
 6         
 7     }
 8     
 9     /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */
10     bool insert(int val) {
11         if (index.find(val) != index.end())
12             return false;
13         index[val] = randomSet.size();
14         randomSet.push_back(val);
15         return true;
16     }
17     
18     /** Removes a value from the set. Returns true if the set contained the specified element. */
19     bool remove(int val) {
20         if (index.find(val) == index.end())
21             return false;
22         randomSet[index[val]] = randomSet.back();
23         index[randomSet.back()] = index[val];
24         randomSet.pop_back();
25         index.erase(val);
26         return true;
27     }
28     
29     /** Get a random element from the set. */
30     int getRandom() {
31         return randomSet[rand()%randomSet.size()];
32     }
33 private:
34     vector<int> randomSet;
35     unordered_map<int, int> index;
36 };
37 
38 /**
39  * Your RandomizedSet object will be instantiated and called as such:
40  * RandomizedSet obj = new RandomizedSet();
41  * bool param_1 = obj.insert(val);
42  * bool param_2 = obj.remove(val);
43  * int param_3 = obj.getRandom();
44  */
View Code

 


381. Insert Delete GetRandom O(1) - Duplicates allowed (hard)

实现一个存、取、删随机数的类,数字可以重复

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

Note: Duplicate elements are allowed.
insert(val): Inserts an item val to the collection.
remove(val): Removes an item val from the collection if present.
getRandom: Returns a random element from current collection of elements. The probability of each element being returned is linearly related to the number of same value the collection contains.
Example:

// Init an empty collection.
RandomizedCollection collection = new RandomizedCollection();

// Inserts 1 to the collection. Returns true as the collection did not contain 1.
collection.insert(1);

// Inserts another 1 to the collection. Returns false as the collection contained 1. Collection now contains [1,1].
collection.insert(1);

// Inserts 2 to the collection, returns true. Collection now contains [1,1,2].
collection.insert(2);

// getRandom should return 1 with the probability 2/3, and returns 2 with the probability 1/3.
collection.getRandom();

// Removes 1 from the collection, returns true. Collection now contains [1,2].
collection.remove(1);

// getRandom should return 1 and 2 both equally likely.
collection.getRandom();
problem
 1 // 把存储的索引变为索引数组,把存的数中添加一个记录反向查询的index
 2 class RandomizedCollection {
 3 public:
 4     /** Initialize your data structure here. */
 5     RandomizedCollection() {
 6         
 7     }
 8     
 9     /** Inserts a value to the collection. Returns true if the collection did not already contain the specified element. */
10     bool insert(int val) {
11         bool res = index.find(val) == index.end();
12         index[val].push_back(nums.size());
13         nums.push_back({val, index[val].size() - 1});
14         return res;
15     }
16     
17     /** Removes a value from the collection. Returns true if the collection contained the specified element. */
18     bool remove(int val) {
19         if (index.find(val) == index.end())
20             return false;
21         index[nums.back().first][nums.back().second] = index[val].back();
22         nums[index[val].back()] = nums.back();
23         index[val].pop_back();
24         nums.pop_back();
25         if (index[val].empty())
26             index.erase(val);
27         return true;
28     }
29     
30     /** Get a random element from the collection. */
31     int getRandom() {
32         return nums[rand()%nums.size()].first;
33     }
34 private:
35     vector<pair<int, int>> nums;
36     unordered_map<int, vector<int>> index;
37 };
38 
39 /**
40  * Your RandomizedCollection object will be instantiated and called as such:
41  * RandomizedCollection obj = new RandomizedCollection();
42  * bool param_1 = obj.insert(val);
43  * bool param_2 = obj.remove(val);
44  * int param_3 = obj.getRandom();
45  */
View Code

 


414. Third Maximum Number (easy)

 

找到第三大的数

 1 Given a non-empty array of integers, return the third maximum number in this array. If it does not exist, return the maximum number. The time complexity must be in O(n).
 2 
 3 Example 1:
 4 Input: [3, 2, 1]
 5 
 6 Output: 1
 7 
 8 Explanation: The third maximum is 1.
 9 Example 2:
10 Input: [1, 2]
11 
12 Output: 2
13 
14 Explanation: The third maximum does not exist, so the maximum (2) is returned instead.
15 Example 3:
16 Input: [2, 2, 3, 1]
17 
18 Output: 1
19 
20 Explanation: Note that the third maximum here means the third maximum distinct number.
21 Both numbers with value 2 are both considered as second maximum.
problem
 1 // 必须用更大的类型存储初始值
 2 int thirdMax(vector<int>& nums) {
 3     long long a, b, c;
 4     a = b = c = LLONG_MIN;
 5     for (auto num : nums) {
 6         if (num <= c || num == b || num == a) continue;
 7         c = num;
 8         if (c > b) swap(b, c);
 9         if (b > a) swap(a, b);
10     }
11     return c == LLONG_MIN ? a : c;
12 }
View Code
 1 // 使用set,利用其顺序,size大于3时删去最小值
 2 class Solution {
 3 public:
 4     int thirdMax(vector<int>& nums) {
 5         set<int> set;
 6         for (int n : nums) {
 7             set.insert(n);
 8             if (set.size() > 3)
 9                 set.erase(set.begin());
10         }
11         return set.size() == 3 ? *set.begin() : *set.rbegin();
12     }
13 };
View Code

 


442. Find All Duplicates in an Array (medium) #

找到所有重复的数,数的范围为1~n,重复最多两次

Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.

Find all the elements that appear twice in this array.

Could you do it without extra space and in O(n) runtime?

Example:
Input:
[4,3,2,7,8,2,3,1]

Output:
[2,3]
problem
 1 class Solution {
 2 public:
 3     vector<int> findDuplicates(vector<int>& nums) {
 4         vector<int> res;
 5         for (int n : nums) {
 6             int index = abs(n) - 1;
 7             if (nums[index] < 0)
 8                 res.push_back(abs(n));
 9             else
10                 nums[index] = -nums[index];
11         }
12         return res;
13     }
14 };
View Code

 


448. Find All Numbers Disappeared in an Array (easy)

找到1~n中丢失的数

Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.

Find all the elements of [1, n] inclusive that do not appear in this array.

Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.

Example:

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

Output:
[5,6]
problem
 1 class Solution {
 2 public:
 3     vector<int> findDisappearedNumbers(vector<int>& nums) {
 4         vector<int> res;
 5         for (int n : nums) {
 6             if (nums[abs(n) - 1] > 0)
 7                 nums[abs(n) - 1] = -nums[abs(n) - 1];
 8         }
 9         for (int i = 0; i < nums.size(); ++i) {
10             if (nums[i] > 0)
11                 res.push_back(i + 1);
12         }
13         return res;
14     }
15 };
View Code

 


485. Max Consecutive Ones (easy)

最长的连续1

Given a binary array, find the maximum number of consecutive 1s in this array.

Example 1:
Input: [1,1,0,1,1,1]
Output: 3
Explanation: The first two digits or the last three digits are consecutive 1s.
    The maximum number of consecutive 1s is 3.
Note:

The input array will only contain 0 and 1.
The length of input array is a positive integer and will not exceed 10,000
problem
 1 class Solution {
 2 public:
 3     int findMaxConsecutiveOnes(vector<int>& nums) {
 4         int count = 0, res = 0;
 5         for (int n : nums) {
 6             if (n) {
 7                 ++count;
 8                 res = max(res, count);
 9             }
10             else
11                 count = 0;
12         }
13         return res;
14     }
15 };
View Code

 


495. Teemo Attacking (medium)

提莫攻击的中毒持续时间

In LOL world, there is a hero called Teemo and his attacking can make his enemy Ashe be in poisoned condition. Now, given the Teemo's attacking ascending time series towards Ashe and the poisoning time duration per Teemo's attacking, you need to output the total time that Ashe is in poisoned condition.

You may assume that Teemo attacks at the very beginning of a specific time point, and makes Ashe be in poisoned condition immediately.

Example 1:
Input: [1,4], 2
Output: 4
Explanation: At time point 1, Teemo starts attacking Ashe and makes Ashe be poisoned immediately. 
This poisoned status will last 2 seconds until the end of time point 2. 
And at time point 4, Teemo attacks Ashe again, and causes Ashe to be in poisoned status for another 2 seconds. 
So you finally need to output 4.
Example 2:
Input: [1,2], 2
Output: 3
Explanation: At time point 1, Teemo starts attacking Ashe and makes Ashe be poisoned. 
This poisoned status will last 2 seconds until the end of time point 2. 
However, at the beginning of time point 2, Teemo attacks Ashe again who is already in poisoned status. 
Since the poisoned status won't add up together, though the second poisoning attack will still work at time point 2, it will stop at the end of time point 3. 
So you finally need to output 3.
Note:
You may assume the length of given time series array won't exceed 10000.
You may assume the numbers in the Teemo's attacking time series and his poisoning time duration per attacking are non-negative integers, which won't exceed 10,000,000.
problem
1 class Solution {
2 public:
3     int findPoisonedDuration(vector<int>& timeSeries, int duration) {
4         int res = 0;
5         for (int i = 1; i < timeSeries.size(); ++i)
6             res += min(timeSeries[i] - timeSeries[i - 1], duration);
7         return timeSeries.size() ? res + duration : 0;
8     }
9 };
View Code

 


532. K-diff Pairs in an Array (easy) #

找到数组中差的绝对值为k的数字对的个数

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

Example 1:
Input: [3, 1, 4, 1, 5], k = 2
Output: 2
Explanation: There are two 2-diff pairs in the array, (1, 3) and (3, 5).
Although we have two 1s in the input, we should only return the number of unique pairs.
Example 2:
Input:[1, 2, 3, 4, 5], k = 1
Output: 4
Explanation: There are four 1-diff pairs in the array, (1, 2), (2, 3), (3, 4) and (4, 5).
Example 3:
Input: [1, 3, 1, 5, 4], k = 0
Output: 1
Explanation: There is one 0-diff pair in the array, (1, 1).
Note:
The pairs (i, j) and (j, i) count as the same pair.
The length of the array won't exceed 10,000.
All the integers in the given input belong to the range: [-1e7, 1e7].
problem
 1 class Solution {
 2 public:
 3     int findPairs(vector<int>& nums, int k) {
 4         if (k < 0)
 5             return 0;
 6         unordered_map<int, int> map;
 7         int res = 0;
 8         for (int n : nums)
 9             ++map[n];
10         if (k == 0) {
11             for (auto pair : map)
12                 if (pair.second > 1)
13                     ++res;
14         }
15         else {
16             for (auto pair : map)
17                 if (map.find(pair.first - k) != map.end() && map[pair.first - k] > 0)
18                     ++res;
19         }
20         return res;
21     }
22 };
View Code

 


560. Subarray Sum Equals K (medium)#

和为k的子集个数

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

Example 1:
Input:nums = [1,1,1], k = 2
Output: 2
Note:
The length of the array is in range [1, 20,000].
The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].
problem
 1 // (m>n)前m个数的和减去前n个数的和为k,即满足要求,因此储存所有前n个数的和,查询前m个的和减去k是否存在
 2 class Solution {
 3 public:
 4     int subarraySum(vector<int>& nums, int k) {
 5         int count = 0, sum = 0;
 6         unordered_map<int, int> map;
 7         map[0] = 1;
 8         for (int n : nums) {
 9             sum += n;
10             if (map.find(sum - k) != map.end())
11                 count += map[sum - k];
12             ++map[sum];
13         }
14         return count;
15     }
16 };
View Code

 


561. Array Partition I (easy)

把2n个数分为n组,每组2个,使得所有组中较小的数求和最小

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:
n is a positive integer, which is in the range of [1, 10000].
All the integers in the array will be in the range of [-10000, 10000].
problem
 1 class Solution {
 2 public:
 3     int arrayPairSum(vector<int>& nums) {
 4         int res = 0;
 5         sort(nums.begin(), nums.end());
 6         for (int i = 0; i < nums.size(); i += 2)
 7             res += nums[i];
 8         return res;
 9     }
10 };
View Code

 


565. Array Nesting (medium)

数组中的最大环

A zero-indexed array A of length N contains all integers from 0 to N-1. Find and return the longest length of set S, where S[i] = {A[i], A[A[i]], A[A[A[i]]], ... } subjected to the rule below.

Suppose the first element in S starts with the selection of element A[i] of index = i, the next element in S should be A[A[i]], and then A[A[A[i]]]… By that analogy, we stop adding right before a duplicate element occurs in S.

Example 1:
Input: A = [5,4,0,3,1,6,2]
Output: 6
Explanation: 
A[0] = 5, A[1] = 4, A[2] = 0, A[3] = 3, A[4] = 1, A[5] = 6, A[6] = 2.

One of the longest S[K]:
S[0] = {A[0], A[5], A[6], A[2]} = {5, 6, 2, 0}
Note:
N is an integer within the range [1, 20,000].
The elements of A are all distinct.
Each element of A is an integer within the range [0, N-1].
problem
 1 class Solution {
 2 public:
 3     int arrayNesting(vector<int>& nums) {
 4         int res = 0;
 5         for (int i = 0; i < nums.size(); ++i) {
 6             int length = 0;
 7             for (int index = i; nums[index] >= 0; ++length) {
 8                 int nextIndex = nums[index];
 9                 nums[index] = -1;
10                 index = nextIndex;
11             }
12             res = max(res, length);
13         }
14         return res;
15     }
16 };
View Code

 


566. Reshape the Matrix (easy)

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

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

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

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

Example 1:
Input: 
nums = 
[[1,2],
 [3,4]]
r = 1, c = 4
Output: 
[[1,2,3,4]]
Explanation:
The row-traversing of nums is [1,2,3,4]. The new reshaped matrix is a 1 * 4 matrix, fill it row by row by using the previous list.
Example 2:
Input: 
nums = 
[[1,2],
 [3,4]]
r = 2, c = 4
Output: 
[[1,2],
 [3,4]]
Explanation:
There is no way to reshape a 2 * 2 matrix to a 2 * 4 matrix. So output the original matrix.
Note:
The height and width of the given matrix is in range [1, 100].
The given r and c are all positive.
problem
 1 class Solution {
 2 public:
 3     vector<vector<int>> matrixReshape(vector<vector<int>>& nums, int r, int c) {
 4         if (nums.empty())
 5             return nums;
 6         int m = nums.size(), n = nums[0].size();
 7         if (m*n != r*c)
 8             return nums;
 9         vector<vector<int>> res(r, vector<int>(c));
10         for (int i = 0; i < r; ++i) {
11             for (int j = 0; j < c; ++j)
12                 res[i][j] = nums[(i*c + j)/n][(i*c + j)%n];
13         }
14         return res;
15     }
16 };
View Code

 


581. Shortest Unsorted Continuous Subarray (easy) #

排序连续的子序列,可使整个序列有序,返回子序列的最长长度。

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

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

Example 1:
Input: [2, 6, 4, 8, 10, 9, 15]
Output: 5
Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order.
Note:
Then length of the input array is in range [1, 10,000].
The input array may contain duplicates, so ascending order here means <=.
problem
 1 class Solution {
 2 public:
 3     int findUnsortedSubarray(vector<int>& nums) {
 4         int length = nums.size(), left = 0, right = -1, maxVal = nums[0], minVal = nums[length - 1];
 5         for (int i = 1; i < nums.size(); ++i) {
 6             maxVal = max(maxVal, nums[i]);
 7             minVal = min(minVal, nums[length - 1 -i]);
 8             if (nums[i] < maxVal) right = i;
 9             if (nums[length - i - 1] > minVal) left = length - i - 1;
10         }
11         return right - left + 1;
12     }
13 };
View Code

 


605. Can Place Flowers (easy)

是否可以再种n个花,且满足左右没花

Suppose you have a long flowerbed in which some of the plots are planted and some are not. However, flowers cannot be planted in adjacent plots - they would compete for water and both would die.

Given a flowerbed (represented as an array containing 0 and 1, where 0 means empty and 1 means not empty), and a number n, return if n new flowers can be planted in it without violating the no-adjacent-flowers rule.

Example 1:
Input: flowerbed = [1,0,0,0,1], n = 1
Output: True
Example 2:
Input: flowerbed = [1,0,0,0,1], n = 2
Output: False
Note:
The input array won't violate no-adjacent-flowers rule.
The input array size is in the range of [1, 20000].
n is a non-negative integer which won't exceed the input array size.
problem
 1 class Solution {
 2 public:
 3     bool canPlaceFlowers(vector<int>& flowerbed, int n) {
 4         int count = 0;
 5         for (int i = 0; i < flowerbed.size(); ++i) {
 6             if ((flowerbed[i] == 0) && (i == 0 || flowerbed[i - 1] == 0) && (i == flowerbed.size() - 1 || flowerbed[i + 1] == 0)) {
 7                 ++count;
 8                 flowerbed[i] = 1;
 9             }
10         }
11         return count >= n;
12     }
13 };
View Code

 


611. Valid Triangle Number (medium) #

所有能组成三角形的组合个数

Given an array consists of non-negative integers, your task is to count the number of triplets chosen from the array that can make triangles if we take them as side lengths of a triangle.
Example 1:
Input: [2,2,3,4]
Output: 3
Explanation:
Valid combinations are: 
2,3,4 (using the first 2)
2,3,4 (using the second 2)
2,2,3
Note:
The length of the given array won't exceed 1000.
The integers in the given array are in the range of [0, 1000].
problem
 1 // O(n^2),length要先提取出来,因为nums.size()是size_t类型,其运算不能小于0
 2 class Solution {
 3 public:
 4     int triangleNumber(vector<int>& nums) {
 5         int res = 0, length = nums.size();
 6         sort(nums.begin(), nums.end());
 7         for (int i = length - 1; i >= 2; --i) {
 8             int left = 0, right = i - 1;
 9             while (left < right) {
10                 if (nums[left] + nums[right] > nums[i]) {
11                     res += right - left;
12                     --right;
13                 }
14                 else
15                     ++left;
16             }
17         }
18         return res;
19     }
20 };
View Code

 


621. Task Scheduler (medium)

同一进程执行间隔最少为n,求一组进程的最小执行时间

Given a char array representing tasks CPU need to do. It contains capital letters A to Z where different letters represent different tasks.Tasks could be done without original order. Each task could be done in one interval. For each interval, CPU could finish one task or just be idle.

However, there is a non-negative cooling interval n that means between two same tasks, there must be at least n intervals that CPU are doing different tasks or just be idle.

You need to return the least number of intervals the CPU will take to finish all the given tasks.

Example 1:
Input: tasks = ["A","A","A","B","B","B"], n = 2
Output: 8
Explanation: A -> B -> idle -> A -> B -> idle -> A -> B.
Note:
The number of tasks is in the range [1, 10000].
The integer n is in the range [0, 100].
problem
 1 class Solution {
 2 public:
 3     int leastInterval(vector<char>& tasks, int n) {
 4         int count[26] = {0}, index;
 5         for (char c : tasks)
 6             ++count[c - 'A'];
 7         sort(count, count + 26);
 8         for (index = 24; index >= 0 && count[index] == count[25]; --index);
 9         return max((int)tasks.size(), (count[25] - 1)*(n + 1) + 25 - index);
10     }
11 };
View Code

 


628. Maximum Product of Three Numbers (easy)

最大的三个数之和

Given an integer array, find three numbers whose product is maximum and output the maximum product.

Example 1:
Input: [1,2,3]
Output: 6
Example 2:
Input: [1,2,3,4]
Output: 24
Note:
The length of the given array will be in range [3,104] and all elements are in the range [-1000, 1000].
Multiplication of any three numbers in the input won't exceed the range of 32-bit signed integer.
problem
 1 class Solution {
 2 public:
 3     int maximumProduct(vector<int>& nums) {
 4         int maxVal[3] = {INT_MIN, INT_MIN, INT_MIN}, minVal[2] = {INT_MAX, INT_MAX};
 5         for (int n : nums) {
 6              if (n > maxVal[0]) {
 7                  maxVal[2] = maxVal[1];
 8                  maxVal[1] = maxVal[0];
 9                  maxVal[0] = n;
10              }
11             else if (n > maxVal[1]) {
12                 maxVal[2] = maxVal[1];
13                 maxVal[1] = n;
14             }
15             else if (n > maxVal[2])
16                 maxVal[2] = n;
17             if (n < minVal[0]) {
18                 minVal[1] = minVal[0];
19                 minVal[0] = n;
20             }
21             else if (n < minVal[1])
22                 minVal[1] = n;
23         }
24         return max(maxVal[0]*maxVal[1]*maxVal[2], maxVal[0]*minVal[0]*minVal[1]);
25     }
26 };
View Code

 


643. Maximum Average Subarray I (easy)

最大的连续k个数的平均数

Given an array consisting of n integers, find the contiguous subarray of given length k that has the maximum average value. And you need to output the maximum average value.

Example 1:
Input: [1,12,-5,-6,50,3], k = 4
Output: 12.75
Explanation: Maximum average is (12-5-6+50)/4 = 51/4 = 12.75
Note:
1 <= k <= n <= 30,000.
Elements of the given array will be in the range [-10,000, 10,000].
problem
 1 class Solution {
 2 public:
 3     double findMaxAverage(vector<int>& nums, int k) {
 4         int sum = 0;
 5         for (int i = 0; i < k; ++i)
 6             sum += nums[i];
 7         int res = sum;
 8         for (int i = k; i < nums.size(); ++i) {
 9             sum += nums[i] - nums[i - k];
10             res = max(res, sum);
11         }
12         return 1.0*res/k;
13     }
14 };
View Code

 


661. Image Smoother (easy)

图像平滑滤波

Given a 2D integer matrix M representing the gray scale of an image, you need to design a smoother to make the gray scale of each cell becomes the average gray scale (rounding down) of all the 8 surrounding cells and itself. If a cell has less than 8 surrounding cells, then use as many as you can.

Example 1:
Input:
[[1,1,1],
 [1,0,1],
 [1,1,1]]
Output:
[[0, 0, 0],
 [0, 0, 0],
 [0, 0, 0]]
Explanation:
For the point (0,0), (0,2), (2,0), (2,2): floor(3/4) = floor(0.75) = 0
For the point (0,1), (1,0), (1,2), (2,1): floor(5/6) = floor(0.83333333) = 0
For the point (1,1): floor(8/9) = floor(0.88888889) = 0
Note:
The value in the given matrix is in the range of [0, 255].
The length and width of the given matrix are in the range of [1, 150].
problem
 1 class Solution {
 2 public:
 3     vector<vector<int>> imageSmoother(vector<vector<int>>& M) {
 4         if (M.empty()) return M;
 5         int row = M.size(), col = M[0].size(), cnt = 0;
 6         vector<vector<int>> res(row, vector<int>(col, 0));
 7         for (int i = 0; i < row; ++i) {
 8             for (int j = 0; j < col; ++j) {
 9                 for (int m = -1; m < 2; ++m) {
10                     for (int n = -1; n < 2; ++n) {
11                         if (i + m >= 0 && i + m < row && j + n >= 0 && j + n < col){
12                             res[i][j] += M[i + m][j + n];
13                             ++cnt;
14                         }
15                     }
16                 }
17                 res[i][j] /= cnt;
18                 cnt = 0;
19             }
20         }
21         return res;
22     }
23 };
View Code

 


665. Non-decreasing Array (easy) #

改一个数,使整个数组降序

Given an array with n integers, your task is to check if it could become non-decreasing by modifying at most 1 element.

We define an array is non-decreasing if array[i] <= array[i + 1] holds for every i (1 <= i < n).

Example 1:
Input: [4,2,3]
Output: True
Explanation: You could modify the first 4 to 1 to get a non-decreasing array.
Example 2:
Input: [4,2,1]
Output: False
Explanation: You can't get a non-decreasing array by modify at most one element.
Note: The n belongs to [1, 10,000].
problem
 1 // 找到nums[i]<nums[i-1],保证(nums[i]>=nums[i-2] || nums[i+1]>=nums[i-1]),如果第一个没有满足,就判断第二个
 2 class Solution {
 3 public:
 4     bool checkPossibility(vector<int>& nums) {
 5         int cnt = 0, lst = nums[0];
 6         for (int i = 1; i < nums.size(); ++i) {
 7             if (nums[i] < lst) {
 8                 if (cnt++ > 0)
 9                     return false;
10                 else if (i > 1 && nums[i - 2] > nums[i])
11                     continue;
12             }
13             lst = nums[i];
14         }
15         return true;
16     }
17 };
View Code

 


667. Beautiful Arrangement II (medium)

将1~n放入数组中,使相邻两个数的差有k种不同情况

Given two integers n and k, you need to construct a list which contains n different positive integers ranging from 1 to n and obeys the following requirement: 
Suppose this list is [a1, a2, a3, ... , an], then the list [|a1 - a2|, |a2 - a3|, |a3 - a4|, ... , |an-1 - an|] has exactly k distinct integers.

If there are multiple answers, print any of them.

Example 1:
Input: n = 3, k = 1
Output: [1, 2, 3]
Explanation: The [1, 2, 3] has three different positive integers ranging from 1 to 3, and the [1, 1] has exactly 1 distinct integer: 1.
Example 2:
Input: n = 3, k = 2
Output: [1, 3, 2]
Explanation: The [1, 3, 2] has three different positive integers ranging from 1 to 3, and the [2, 1] has exactly 2 distinct integers: 1 and 2.
Note:
The n and k are in the range 1 <= k < n <= 104.
problem
 1 class Solution {
 2 public:
 3     vector<int> constructArray(int n, int k) {
 4         vector<int> res;
 5         for (int i = 1, j = n; i <= j; ) {
 6             if (k > 1) {
 7                 res.push_back(k-- % 2 ? i++ : j--);
 8             }
 9             else {
10                 res.push_back(i++);
11             }
12         }
13         return res;
14     }
15 };
View Code
 1 class Solution {
 2 public:
 3     vector<int> constructArray(int n, int k) {
 4         vector<int> res = {1};
 5         int num = 1;
 6         for (int i = 1; i < n; ++i) {
 7             if (abs(k) > 0) {
 8                 num += k;
 9                 k = k > 0 ? -k + 1 : -(k + 1);
10                 res.push_back(num);
11             }
12             else
13                 res.push_back(i + 1);
14         }
15         return res;
16     }
17 };
View Code

 


670. Maximum Swap (medium) #

把整数的某两位互换,最多一次,找到最大的互换后的数

Given a non-negative integer, you could swap two digits at most once to get the maximum valued number. Return the maximum valued number you could get.

Example 1:
Input: 2736
Output: 7236
Explanation: Swap the number 2 and the number 7.
Example 2:
Input: 9973
Output: 9973
Explanation: No swap.
Note:
The given number is in the range [0, 108]
problem
 1 class Solution {
 2 public:
 3     int maximumSwap(int num) {
 4         string numString = to_string(num);
 5         vector<int> maxIndex(10, -1);
 6         for (int i = 0; i < numString.size(); ++i)
 7             maxIndex[numString[i] - '0'] = i;
 8         for (int i = 0; i < numString.size(); ++i) {
 9             for (int j = 9; j > numString[i] - '0'; --j) {
10                 if (maxIndex[j] > i) {
11                     swap(numString[i], numString[maxIndex[j]]);
12                     return stoi(numString);
13                 }
14             }
15         }
16         return num;
17     }
18 };
View Code
 1 class Solution {
 2 public:
 3     int maximumSwap(int num) {
 4         string numString = to_string(num);
 5         int curIndex = numString.size() - 1;
 6         vector<int> maxIndex(numString.size(), -1);
 7         for (int i = numString.size() - 1; i >= 0; --i) {
 8             if (numString[i] > numString[curIndex]) 
 9                 curIndex = i;
10             maxIndex[i] = curIndex;
11         }
12         for (int i = 0; i < numString.size(); ++i) {
13             if (numString[i] < numString[maxIndex[i]]) {
14                 swap(numString[i], numString[maxIndex[i]]);
15                 return stoi(numString);
16             }
17         }
18         return num;
19     }
20 };
View Code
 1 class Solution {
 2 public:
 3     int maximumSwap(int num) {
 4         int right = INT_MIN, rightIndex = 0, left = -1, leftIndex = 0, lst = num%10, cur, maxN = INT_MIN, maxIndex;
 5         for (int tmp = num, cnt = 0; tmp /= 10; ++cnt) {
 6             cur = tmp%10;
 7             if (lst > maxN) {
 8                 maxN = lst;
 9                 maxIndex = cnt;
10             }
11             if (cur < lst){
12                 right = maxN;
13                 rightIndex = maxIndex;
14             }
15             if (cur < right) {
16                 left = cur;
17                 leftIndex = cnt + 1;
18             }
19             lst = cur;
20         }
21         return left == -1 ? num : num - left*pow(10, leftIndex) - right*pow(10, rightIndex) + right*pow(10, leftIndex) + left*pow(10, rightIndex);
22     }
23 };
my solution

 


674. Longest Continuous Increasing Subsequence (easy)

最长的连续增长子序列

Given an unsorted array of integers, find the length of longest continuous increasing subsequence (subarray).

Example 1:
Input: [1,3,5,4,7]
Output: 3
Explanation: The longest continuous increasing subsequence is [1,3,5], its length is 3. 
Even though [1,3,5,7] is also an increasing subsequence, it's not a continuous one where 5 and 7 are separated by 4. 
Example 2:
Input: [2,2,2,2,2]
Output: 1
Explanation: The longest continuous increasing subsequence is [2], its length is 1. 
Note: Length of the array will not exceed 10,000.
problem
 1 class Solution {
 2 public:
 3     int findLengthOfLCIS(vector<int>& nums) {
 4         if (nums.empty())
 5             return 0;
 6         int res = 0, lst = nums[0], cnt = 1;
 7         for (int i = 1; i < nums.size(); ++i) {
 8             if (nums[i] > nums[i - 1])
 9                 ++cnt;
10             else {
11                 res = max(res, cnt);
12                 cnt = 1;
13             }
14         }
15         return max(res, cnt);
16     }
17 };
View Code

 


689. Maximum Sum of 3 Non-Overlapping Subarrays (hard) #

找到三个不重叠的连续子集,长度都是k,使和最大

In a given array nums of positive integers, find three non-overlapping subarrays with maximum sum.

Each subarray will be of size k, and we want to maximize the sum of all 3*k entries.

Return the result as a list of indices representing the starting position of each interval (0-indexed). If there are multiple answers, return the lexicographically smallest one.

Example:
Input: [1,2,1,2,6,7,5,1], 2
Output: [0, 3, 5]
Explanation: Subarrays [1, 2], [2, 6], [7, 5] correspond to the starting indices [0, 3, 5].
We could have also taken [2, 1], but an answer of [1, 3, 5] would be lexicographically larger.
Note:
nums.length will be between 1 and 20000.
nums[i] will be between 1 and 65535.
k will be between 1 and floor(nums.length / 3).
problem
 1 // 动态规划,先算左右,再算中间
 2 class Solution {
 3 public:
 4     vector<int> maxSumOfThreeSubarrays(vector<int>& nums, int k) {
 5         int length = nums.size(), maxLeft = INT_MIN, maxRight = INT_MIN, maxSum = INT_MIN;
 6         vector<int> num(length - k + 1, 0), left(length - k + 1), right(length - k + 1), res(3);
 7         for (int i = 0; i < nums.size(); ++i) {
 8             if (i < k)
 9                 num[0] += nums[i];
10             else
11                 num[i - k + 1] = num[i - k] + nums[i] - nums[i - k];
12         }
13         for (int i = 0; i < length - k + 1; ++i) {
14             if (num[i] > maxLeft) {
15                 maxLeft = num[i];
16                 left[i] = i;
17             }
18             else
19                 left[i] = left[i - 1];
20             if (num[length - i - k] > maxRight) {
21                 maxRight = num[length - i - k];
22                 right[length - i - k] = length - i - k;
23             }
24             else
25                 right[length - i - k] = right[length - i - k + 1];
26         }
27         for (int m = k; m <= length - k*2; ++m) {
28             int sum = num[left[m - k]] + num[right[m + k]] + num[m];
29             if (maxSum < sum) {
30                 maxSum = sum;
31                 res = {left[m - k], m, right[m + k]};
32             }
33         }
34         return res;
35     }
36 };
View Code

 


695. Max Area of Island (easy)

最大的岛屿面积

Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water.

Find the maximum area of an island in the given 2D array. (If there is no island, the maximum area is 0.)

Example 1:
[[0,0,1,0,0,0,0,1,0,0,0,0,0],
 [0,0,0,0,0,0,0,1,1,1,0,0,0],
 [0,1,1,0,1,0,0,0,0,0,0,0,0],
 [0,1,0,0,1,1,0,0,1,0,1,0,0],
 [0,1,0,0,1,1,0,0,1,1,1,0,0],
 [0,0,0,0,0,0,0,0,0,0,1,0,0],
 [0,0,0,0,0,0,0,1,1,1,0,0,0],
 [0,0,0,0,0,0,0,1,1,0,0,0,0]]
Given the above grid, return 6. Note the answer is not 11, because the island must be connected 4-directionally.
Example 2:
[[0,0,0,0,0,0,0,0]]
Given the above grid, return 0.
Note: The length of each dimension in the given grid does not exceed 50.
problem
 1 class Solution {
 2 public:
 3     int maxAreaOfIsland(vector<vector<int>>& grid) {
 4         if (grid.empty())
 5             return 0;
 6         int m = grid.size(), n = grid[0].size(), res = 0;
 7         for (int i = 0; i < m; ++i) {
 8             for (int j = 0; j < n; ++j) {
 9                 if (grid[i][j] == 1) {
10                     res = max(res, 1 + findNeibors(grid, i, j));
11                 }
12             }
13         }
14         return res;
15     }
16     int findNeibors(vector<vector<int>>& grid, int i, int j) {
17         grid[i][j] = -1;
18         int res = 0;
19         if (i - 1 >= 0 && grid[i - 1][j] == 1)
20             res += 1 + findNeibors(grid, i - 1, j);
21         if (i + 1 < grid.size() && grid[i + 1][j] == 1)
22             res += 1 + findNeibors(grid, i + 1, j);
23         if (j - 1 >= 0 && grid[i][j - 1] == 1)
24             res += 1 + findNeibors(grid, i, j - 1);
25         if (j + 1 < grid[0].size() && grid[i][j + 1] == 1)
26             res += 1 + findNeibors(grid, i, j + 1);
27         return res;
28     }
29 };
View Code

 


697. Degree of an Array (easy)

数组中频率最高的数,包含这个数的最小子集长度

Given a non-empty array of non-negative integers nums, the degree of this array is defined as the maximum frequency of any one of its elements.

Your task is to find the smallest possible length of a (contiguous) subarray of nums, that has the same degree as nums.

Example 1:
Input: [1, 2, 2, 3, 1]
Output: 2
Explanation: 
The input array has a degree of 2 because both elements 1 and 2 appear twice.
Of the subarrays that have the same degree:
[1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]
The shortest length is 2. So return 2.
Example 2:
Input: [1,2,2,3,1,4,2]
Output: 6
Note:

nums.length will be between 1 and 50,000.
nums[i] will be an integer between 0 and 49,999.
problem
 1 class Solution {
 2 public:
 3     int findShortestSubArray(vector<int>& nums) {
 4         int freq = 0, res = INT_MAX;
 5         unordered_map<int, vector<int>> mp;
 6         for (int i = 0; i < nums.size(); ++i) {
 7             if (mp.find(nums[i]) == mp.end())
 8                 mp[nums[i]] = {1, i, i};
 9             else {
10                 mp[nums[i]][0] += 1;
11                 mp[nums[i]][2] = i;
12             }
13         }
14         for (auto m : mp) {
15             if (m.second[0] > freq) {
16                 freq = m.second[0];
17                 res = m.second[2] - m.second[1] + 1;
18             }
19             else if (m.second[0] == freq)
20                 res = min(res, m.second[2] - m.second[1] + 1);
21         }
22         return res;
23     }
24 };
View Code

 

posted @ 2017-12-01 17:24  zz091207  阅读(248)  评论(0编辑  收藏  举报