LC4 Median of Two Sorted Arrays
Problem
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)).
You may assume nums1 and nums2 cannot be both empty.
Example 1:
1
2
3
4 nums1 = [1, 3]
nums2 = [2]
The median is 2.0Example 2:
1
2
3
4 nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5
Think
由于nums1和nums2都是有序的,所以对这两个数组,一定存在一个分割,使得在分割左半边的nums1和nums2的长度等于右边,且满足左边的最大值小于右边的最小值。
设nums1分割位于nums1[i - 1]和nums1[i]之间,nums2分割位于nums2[j - 1]和nums2[j]之间,且有
设left和right来对nums1进行二分,二分的条件即为上述关系式1&2。
最后根据m+n的奇偶情况判断应该返回maxLeft还是(maxLeft + minRight) / 2。
Code
1 | double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) { |
LC29 Divide Two Integers
Problem
Given two integers
dividend
anddivisor
, divide two integers without using multiplication, division and mod operator.Return the quotient after dividing
dividend
bydivisor
.The integer division should truncate toward zero, which means losing its fractional part. For example,
truncate(8.345) = 8
andtruncate(-2.7335) = -2
.Example 1:
1
2
3 Input: dividend = 10, divisor = 3
Output: 3
Explanation: 10/3 = truncate(3.33333..) = 3.Example 2:
1
2
3 Input: dividend = 7, divisor = -3
Output: -2
Explanation: 7/-3 = truncate(-2.33333..) = -2.Note:
- Both dividend and divisor will be 32-bit signed integers.
- The divisor will never be 0.
- Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. For the purpose of this problem, assume that your function returns 231 − 1 when the division result overflows.
Think
- Approach 1
设被除数为dividend,除数为divisor,初始化结果res=0
当dividend >= divisor的时候,找到当前最大的n满足,res += n,然后在dividend上减去,进行下一次循环;
由于int的范围为,如果一正一负,可能会导致一开始的结果溢出,所以需要将被除数和除数都转化为负数,然后再进行上述计算。
- Approach 2
在Approach 1的基础上,首先将除数的所有小于被除数的2的幂次乘积存储在数组里,然后直接去读取数组即可。
Code
- Approach 1
1 | int HALF_INT_MIN = -1073741824; |
- Approach 2
1 | int HALF_INT_MIN = -1073741824; |
LC33 Search in Rotated Sorted Array
Problem
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.
Your algorithm’s runtime complexity must be in the order of O(log n).
Example 1:
1
2 Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4Example 2:
1
2 Input: nums = [4,5,6,7,0,1,2], target = 3
Output: -1
Think
二分,初始化left=0,right=n - 1
当left < right的时候,
如果nums[mid] == target,则直接返回mid,
如果nums[mid] < taget,通过和nums[left]比较来判断mid当前是在左上升区间还是右上升区间
如果nums[mid] > taget,通过和nums[left]比较来判断mid当前是在左上升区间还是右上升区间
Code
1 | int search(vector<int>& nums, int target) { |
LC34 Find First and Last Position of Element in Sorted Array
Problem
Given an array of integers
nums
sorted in ascending order, find the starting and ending position of a giventarget
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]
.Example 1:
1
2 Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]Example 2:
1
2 Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]
Think
分两次二分查找,分别查找左端点和右端点
Code
1 | vector<int> searchRange(vector<int>& nums, int target) { |
LC35 Search Insert Position
Problem
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:
1
2 Input: [1,3,5,6], 5
Output: 2Example 2:
1
2 Input: [1,3,5,6], 2
Output: 1Example 3:
1
2 Input: [1,3,5,6], 7
Output: 4Example 4:
1
2 Input: [1,3,5,6], 0
Output: 0
Think
普通的二分,如果不在数组里,则插入的位置恰好就是最终left = right的位置。
Code
1 | int searchInsert(vector<int>& nums, int target) { |
LC50 Pow(x, n)
Problem
Implement pow(x, n), which calculates x raised to the power n (xn).
Example 1:
1
2 Input: 2.00000, 10
Output: 1024.00000Example 2:
1
2 Input: 2.10000, 3
Output: 9.26100Example 3:
1
2
3 Input: 2.00000, -2
Output: 0.25000
Explanation: 2-2 = 1/22 = 1/4 = 0.25Note:
- -100.0 < x < 100.0
- n is a 32-bit signed integer, within the range [−231, 231 − 1]
Think
二分,注意INT_MIN在变成正数时会溢出,需要先+1处理一下
Code
1 | double myPow(double x, int n) { |
LC69 Sqrt(x)
Problem
Implement
int sqrt(int x)
.Compute and return the square root of x, where x is guaranteed to be a non-negative integer.
Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.
Example 1:
1
2 Input: 4
Output: 2Example 2:
1
2
3
4 Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since
the decimal part is truncated, 2 is returned.
Think
二分法,设置left和right,表示结果在[left, right]内
如果mid*mid=target则直接返回,如果mid*mid<target,说明结果应该在[mid+1, right]内,否则结果应该在[left, mid-1]内。
Code
1 | int mySqrt(int x) { |
LC74 Search a 2D Matrix
Problem
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.
Example 1:
1
2
3
4
5
6
7
8 Input:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 3
Output: trueExample 2:
1
2
3
4
5
6
7
8 Input:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 13
Output: false
Think
二分,初始left=0,right=m * n即可。
Code
1 | bool searchMatrix(vector<vector<int>>& matrix, int target) { |
LC81 Search in Rotated Sorted Array II
Problem
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand.
(i.e.,
[0,0,1,2,2,5,6]
might become[2,5,6,0,0,1,2]
).You are given a target value to search. If found in the array return
true
, otherwise returnfalse
.Example 1:
1
2 Input: nums = [2,5,6,0,0,1,2], target = 0
Output: trueExample 2:
1
2 Input: nums = [2,5,6,0,0,1,2], target = 3
Output: falseFollow up:
- This is a follow up problem to Search in Rotated Sorted Array, where
nums
may contain duplicates.- Would this affect the run-time complexity? How and why?
Think
在LC33-Search-in-Rotated-Sorted-Array的基础上,注意判断一下当前nums[mid]=num等于nums[left]的时候,这个时候mid可能在左上升区间也可能在右上升区间,所以此时只能将left+1,相当于跳过最左端的部分。
Code
1 | bool search(vector<int>& nums, int target) { |
LC153 Find Minimum in Rotated Sorted Array
Problem
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.
Example 1:
1
2 Input: [3,4,5,1,2]
Output: 1Example 2:
1
2 Input: [4,5,6,7,0,1,2]
Output: 0
Think
二分,设置left和right,我们要找的分界点的特点是大于其右边的值,范围为[left, right],因此有:
当nums[mid] < nums[right]的时候,说明mid在右上升区间,因此right = mid;
当nums[mid] > nums[right]的时候,说明mid在左上升区间,因此left = mid + 1;
注意这里只能和nums[right]比较,因为nums[right]一定在右上升区间上,但是left可能不在左上升区间上。
Code
1 | int findMin(vector<int>& nums) { |
LC154 Find Minimum in Rotated Sorted Array II
Problem
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.
Example 1:
1
2 Input: [1,3,5]
Output: 1Example 2:
1
2 Input: [2,2,2,0,1]
Output: 0Note:
- This is a follow up problem to Find Minimum in Rotated Sorted Array.
- Would allow duplicates affect the run-time complexity? How and why?
Think
二分法,在LC153 Find Minimum in Rotated Sorted Array的基础上,当nums[mid] == nums[right]的时候,根据上题分析,left可能不在左上升区间上,此时left即为要求的结果,而right必定不可能为要求解的结果,因此此处将right -= 1即可,而不可以left += 1.
Code
1 | int findMin(vector<int>& nums) { |
LC167 Two Sum II - Input array is sorted
Problem
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.
Note:
- 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.
Example:
1
2
3 Input: numbers = [2,7,11,15], target = 9
Output: [1,2]
Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2.
Think
- Approach 1
二分,确定一个找另一个
- Approach 2
双指针,nums[left]+nums[right] > target的时候right–,< target的时候left++;
Code
- Approach 1
1 | vector<int> twoSum(vector<int>& numbers, int target) { |
- Approach 2
1 | vector<int> twoSum(vector<int>& nums, int target) { |
Review
对于二分搜索的题目来说,最重要的是
- 确定left和right的初值;
- 确定我们要求的值是在[left, right]还是[left, right);
- 内部分至少三种情况,f(mid) == target,f(mid) < target,f(mid) > target,注意这里就算f(mid) == target也不一定代表可以直接返回结果,因为可能存在相同值的情况;
- 循环结束,如果循环的条件是left <= right,则循环 结束代表没有找到需要的值;如果循环的条件是left < right,则需要单独判断一下left=right处的值是否符合条件。