704. Binary Search
可以用二分法的两个条件:
1.数组是有序的
2.数组是不重复的
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0, right = nums.size()-1;
while(left <= right){
int mid = left + (right-left)/2;
if(nums[mid] == target)
return mid;
if(nums[mid] > target){
right = mid-1;
}else{
left = mid+1;
}
}
return -1;
}
};
注意区间:
当right = nums.size()-1;就意味着这时一个左闭右闭的区间,相应的 循环条件为 left <= right,
left和right的取值也为mid+1 和mid-1
35. Search Insert Position
左闭右闭和左闭右开都试了一下,这道题感觉左闭右开比较好一些,若是左闭右闭,需要进行边界条件的判断
左闭右开:
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int left = 0, right = nums.size();
while(left < right){
int mid = left + (right-left)/2;
if(nums[mid] == target)
return mid;
if(nums[mid] < target)
left = mid +1;
else if(nums[mid] > target)
right = mid;
}
return left;
}
};
左闭右闭:
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int left = 0, right = nums.size()-1;
while(left <= right){
int mid = left + (right-left)/2;
if(nums[mid] == target)
return mid;
if(nums[mid] < target)
left = mid +1;
else if(nums[mid] > target)
right = mid-1;
}
if(left < 0){
left = 0;
}else if(left >= nums.size()){
left = nums.size();
}else{
left = nums[left] > target ? left : left +1;
}
return left;
}
};
两个小问题:
1.left < 0是不需要判断的
2.右边超出边界值的条件是>= nums.size()
34. Find First and Last Position of Element in Sorted Array
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int left = left_bound(nums, target);
int right = right_bound(nums, target);
return {left, right};
}
int left_bound(vector<int>& nums, int target){
int left =0, right = nums.size();
while(left < right){
int mid = left + (right-left)/2;
if(nums[mid] < target)
left = mid + 1;
else if(nums[mid] > target)
right = mid;
else{
right = mid;
}
}
if(left < nums.size() && nums[left] == target) return left;
return -1;
}
int right_bound(vector<int>& nums, int target){
int left =0, right = nums.size();
while(left < right){
int mid = left + (right-left)/2;
if(nums[mid] < target)
left = mid + 1;
else if(nums[mid] > target)
right = mid;
else{
left = mid +1;
}
}
if(right > 0 && nums[right-1] == target) return right-1;
return -1;
}
};
依旧是判断边界的时候出现了问题
可以这样理解:当寻找做边界的时候是右边在动,那么左侧就是准确的,左侧只会越来越大,那么只需要看left是否超过右边界即可。因为left是准确的,所以返回左侧的值,返回left即可。
当寻找右边界的时候,左侧在动,那么右边的是准确的,因为right为开,所以返回的是left-1(或者right-1)
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int left = left_bound(nums, target);
int right = right_bound(nums, target);
return {left, right};
}
int left_bound(vector<int>& nums, int target){
int left =0, right = nums.size()-1;
while(left <= right){
int mid = left + (right-left)/2;
if(nums[mid] < target)
left = mid + 1;
else if(nums[mid] > target)
right = mid-1;
else{
right = mid-1;
}
}
if(left < nums.size() && nums[left] == target) return left;
return -1;
}
int right_bound(vector<int>& nums, int target){
int left =0, right = nums.size()-1;
while(left <= right){
int mid = left + (right-left)/2;
if(nums[mid] < target)
left = mid + 1;
else if(nums[mid] > target)
right = mid-1;
else{
left = mid +1;
}
}
if(right >= 0 && nums[right] == target) return right;
return -1;
}
};
27. Remove Element
快慢指针
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slow = 0, fast = 0;
while(fast < nums.size()){
if(nums[fast] != val){
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}
};
167. Two Sum II - Input Array Is Sorted
左右指针
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
int left =0, right = numbers.size()-1;
while(left < right){
if(numbers[left]+numbers[right] == target)
return {left+1, right+1};
else if(numbers[left]+numbers[right] > target)
right--;
else left++;
}
return {-1, -1};
}
};
需要的限定条件:
1.有序且无重复的数组
2.只有一组答案
注意:
index从1开始
26. Remove Duplicates from Sorted Array
快慢指针
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int slow = 0, fast = 0;
while(fast < nums.size()){
if(nums[fast] != nums[slow]){
slow++;
nums[slow] = nums[fast];
}
fast++;
}
return slow+1;
}
};
注意:
这里要先slow++再赋值
283. Move Zeroes
快慢指针
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int slow =0, fast =0;
while(fast < nums.size()){
if(nums[fast] != 0){
nums[slow] = nums[fast];
slow++;
}
fast++;
}
for(int i = slow; i<nums.size(); i++)
nums[i] = 0;
}
};