二分查找
题目链接
思路
二分查找关键在于边界如何处理,有左闭右开和左闭右闭两种形式
左闭右开
class Solution {
public int search(int[] nums, int target) {
int left = 0, right = nums.length;
while(left < right) {
int mid = left + (right - left)/2;
if (nums[mid] > target) {
right = mid;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
return mid;
}
}
return -1;
}
左闭右闭
class Solution {
public int search(int[] nums, int target) {
int left = 0, right = nums.length - 1;
while(left <= right) {
int mid = left + (right - left)/2;
if (nums[mid] > target) {
right = mid - 1;
} else if (nums[mid] < target) {
left = mid + 1;
} else {
return mid;
}
}
return -1;
}
移除元素
题目链接
https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html
思路
暴力解法,从头到尾遍历,遇到要删除的元素,后面元素左移覆盖
public int removeElement(int[] nums, int val) {
int size = nums.length;
for(int i = 0; i < size; i++) {
if (nums[i] == val) {
for(int j = i + 1; j < size; j++) {
nums[j - 1] = nums[j];
}
size--;
i--;
}
}
return size;
}
快慢指针法
慢指针指向要删除的元素,快指针往前走,直到找到符合条件的,和慢指针交换,慢指针变为快指针
public int removeElement(int[] nums, int val) {
int left = 0, right = 0;
while(right < nums.length) {
if (nums[left] == val) {
while(right < nums.length && nums[right] == val) {
right++;
}
if (right < nums.length) {
nums[left++] = nums[right++];
nums[right - 1] = val;
}
} else {
left++;
right++;
}
}
return left;
}
-
没有理解快慢指针精髓
优先移动快指针,而且移动的是快指针,那就应该用快指针比较,不能用慢指针
参考卡哥的方法public int removeElement(int[] nums, int val) { int left = 0, right = 0; while(right < nums.length) { if (nums[right] != val) { nums[left++] = nums[right++]; } else { right++; } } return left; }
还有双指针写法,从左找=指定值元素,从右找<>指定值元素,交换
public int removeElement(int[] nums, int val) {
int left = 0,right = nums.length - 1;
while(left <=right) {
while(left <= right && nums[left] != val) {
left++;
}
while(left <= right && nums[right] == val) {
right--;
}
if (left < right) {
nums[left++] = nums[right--];
}
}
return left;
}