前言
LeetCode题目:704、27
Takeaway:二分法边界处理、快慢指针
一、LeetCode 704
1.闭区间
定义 target 是在一个在左闭右闭的区间里,也就是[left, right]
#include<vector>
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size()-1;
while(left <= right){
int mid = left+(right-left)/2;
if(nums[mid] == target){
return mid;
}else if(nums[mid] > target){
right = mid-1;
}else{
left = mid+1;
}
}
return -1;
}
};
2.开区间
定义target 是在一个在左闭右开的区间里,也就是[left, right)
#include<vector>
class Solution {
public:
int search(vector<int>& nums, int target) {
int left = 0;
int right = nums.size()-1;
while(left < right){
int mid = left+(right-left)/2;
if(nums[mid] == target){
return mid;
}else if(nums[mid] > target){
right = mid;
}else{
left = mid+1;
}
}
return -1;
}
};
二、LeetCode 27
1.暴力求解
暴力直接两个for循环嵌套做,第一个for循环用来寻找目标元素,第二个for循环用来将后面元素全部前移1,别忘了修改size的大小就行。i也要减一,因为集体前移了
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int size = nums.size();
for(int i=0; i<size; i++){
if(nums[i] == val){
for(int j=i+1; j<size; j++){
// 这样写可以避免 j+1溢出
nums[j-1] = nums[j];
}
size--;
i--;
}
}
return size;
}
};
2.快慢指针
通过快慢指针,快指针用来寻找下一个要移动到慢指针当前位置的元素,慢指针用来标记将要被替换的元素。
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int p_slow = 0;
int p_quick = 0;
for(; p_quick<nums.size(); p_quick++){
if(nums[p_quick] != val){
nums[p_slow] = nums[p_quick];
p_slow++;
}
}
return p_slow;
}
};
总结
703,两种不同形式的二分法,区别在区间的划分。
PS:找中间mid,用left+(right-left)/2,这样可以防止溢出。
27,两种不同的解法,第一种暴力求解,时间复杂度O(n^2);第二种解法是快慢指针, 时间复杂度O(n)。
PS:第二层循环用j-1找元素,这样可以防止j+1导致的栈溢出。