1、求开方
69. Sqrt(x)(Easy)
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:
Input: 4
Output: 2
Example 2:
Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842…, and since the decimal part is truncated, 2 is returned.
class Solution {
public:
int mySqrt(int x) {
if(x<1)
return x;
int low=1,high=x;
while(high>=low)
{
int mid=low+(high-low)/2;
int tmp=x/mid;
if(tmp==mid)
return mid;
else if(tmp>mid)
low=mid+1;
else
high=mid-1;
}
return high;
}
};
2、找大于给定字符的最小字符
744. Find Smallest Letter Greater Than Target(Easy)
Given a list of sorted characters letters containing only lowercase letters, and given a target letter target, find the smallest element in the list that is larger than the given target.
Letters also wrap around. For example, if the target is target = ‘z’ and letters = [‘a’, ‘b’], the answer is ‘a’.
Examples:
Input:
letters = [“c”, “f”, “j”]
target = “a”
Output: “c”
Input:
letters = [“c”, “f”, “j”]
target = “c”
Output: “f”
Input:
letters = [“c”, “f”, “j”]
target = “d”
Output: “f”
Input:
letters = [“c”, “f”, “j”]
target = “g”
Output: “j”
Input:
letters = [“c”, “f”, “j”]
target = “j”
Output: “c”
Input:
letters = [“c”, “f”, “j”]
target = “k”
Output: “c”
Note:
- letters has a length in range [2, 10000].
- letters consists of lowercase letters, and contains at least 2 unique letters.
- target is a lowercase letter.
问题分析:
该实现和正常实现有以下不同:
- 循环条件为 low < high
- high 的赋值表达式为 high = mid
- 最后返回 letters[low]
在 target < letters[mid] 的情况下,可以推导出最左 target 位于 [low, mid] 区间中,这是一个闭区间。high 的赋值表达式为 high = mid,因为 mid 位置也可能是解。
在 target >= letters[mid] 的情况下,解的区间为 [mid+1,high]
class Solution {
public:
char nextGreatestLetter(vector<char>& letters, char target) {
int low=0,high=letters.size()-1;
if(target>=letters[high])
return letters[0];
while(low<high)
{
int mid=low+(high-low)/2;
if(letters[mid]>target)
high=mid;
else
low=mid+1;
}
return letters[low];
}
};
3、排序重复数组中找出现一次的数
540. Single Element in a Sorted Array(Medium)
Given a sorted array consisting of only integers where every element appears twice except for one element which appears once. Find this single element that appears only once.
Example 1:
Input: [1,1,2,3,3,4,4,8,8]
Output: 2
Example 2:
Input: [3,3,7,7,10,11,11]
Output: 10
Note: Your solution should run in O(log n) time and O(1) space.
排序数组中每个元素出现两次,只有一个元素出现一次。 找到这个出现一次的元素。
问题分析:
二分法,每次让 mid 位于序号为偶数的元素上。
如果目标元素在 mid 右边,一定有 nums[mid]==nums[mid+1],目标元素范围更新为 [mid+2,right];
如果目标元素为 mid 或者在 mid 左边,一定有 nums[mid]!=nums[mid+1],目标元素范围更新为 [left,mid]。
class Solution {
public:
int singleNonDuplicate(vector<int>& nums){
int left=0,right=nums.size()-1;
while(left<right)
{
int mid=left+(right-left)/2;
if(mid%2)
mid--;
if(nums[mid]==nums[mid+1])
left=mid+2;
else
right=mid;
}
return nums[left];
}
};
4、第一个出错的版本
278. First Bad Version(Easy)
给定 n 表示有 n 个版本,如果一个版本出错,后面所有的版本都会出错,找出第一个出错的版本。可以调用 isBadVersion(int x) 知道某个版本是否错误。
Example:
Given n = 5, and version = 4 is the first bad version.
call isBadVersion(3) -> false
call isBadVersion(5) -> true
call isBadVersion(4) -> true
Then 4 is the first bad version.
二分法,如果版本 mid 出错,则第一个错误版本位于区间 [left,mid] 中;
如果版本 mid 未出错,则第一个错误版本位于区间 [mid+1,right] 中。
// Forward declaration of isBadVersion API.
bool isBadVersion(int version);
class Solution {
public:
int firstBadVersion(int n) {
int left=0,right=n;
while(right>left)
{
int mid=left+(right-left)/2;
if(isBadVersion(mid))
right=mid;
else
left=mid+1;
}
return left;
}
};
5、旋转数组最小值
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.
Example 1:
Input: [3,4,5,1,2]
Output: 1
Example 2:
Input: [4,5,6,7,0,1,2]
Output: 0
问题分析:
旋转之后,右侧的数据一定小于左侧的数据,如果 nums[mid]>nums[right],则最小值在 mid 右侧,新的区间更新为 [mid+1,right], nums[mid]<nums[right],则最小值在 mid 及 mid 左侧,区间更新为 [left,mid]。
class Solution {
public:
int findMin(vector<int>& nums) {
int left=0,right=nums.size()-1;
while(right>left)
{
int mid=left+(right-left)/2;
if(nums[mid]>nums[right])
left=mid+1;
else
right=mid;
}
return nums[left];
}
};
6、目标数在排序数组中出现的首尾位置
34. Find First and Last Position of Element in Sorted Array(Medium)
Given an array of integers nums 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].
Example 1:
Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]
Example 2:
Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]
问题分析:
用二分找到出现目标的最左侧的位置,然后累加找右侧的位置,累加时注意不要越界。
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int>res(2,-1);
if(nums.size()==0)
return res;
int left=BinarySearch(nums, target);
if(nums[left]!=target)//目标没有出现
return res;
res[0]=left;
int tmp=left+1;
while(tmp<nums.size()&&nums[tmp]==nums[left])//不能越界访问
tmp++;
res[1]=tmp-1;
return res;
}
int BinarySearch(vector<int>& nums, int target)//二分找到出现目标数最左侧的位置
{
int left=0,right=nums.size()-1;
int mid;
while(right>left)
{
mid=left+(right-left)/2;
if(nums[mid]>=target)
right=mid;
else
left=mid+1;
}
return left;
}
};