目录
704. 二分查找题目
解题思路:
左闭右闭时右边界是包括在内的,因此right = nums.length - 1,while循环终止的条件不断缩小左右边界直到左右边界相等时,循环终止;
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1;
while(left <= right){
int middle = left + (right - left ) / 2;
if(nums[middle] > target){
right = middle - 1;
}else if(nums[middle] < target){
left = middle + 1;
}else{
return middle;
}
}
return -1;
}
}
左闭右开右边界是不包括在内的,因此right = nums.length,此时while循环条件的停止条件是left<right的时候区间才有意义,等于的话比如[1,1),这个区间是不存在的
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length ;
while(left < right){
int middle = left + (right - left ) / 2;
if(nums[middle] > target){
right = middle;
}else if(nums[middle] < target){
left = middle + 1;
}else if(nums[middle] == target){
return middle;
}
}
return -1;
}
}
防止溢出的两种方式:middle = left +((right - left)/ 2)、位运算右移一位middle = left+((right - left)>>2)
27. 移除元素
解题思路:
暴力解法:使用两层for循环,如果外循环定位到要删除元素的位置,内循环就要将此位置之后的所有元素都要往前移动一位,但是要注意移动之后下标i也要向前移动一位,因为下标i以后的数值都向前移动了一位,否则会漏掉对刚往前移动的第一个位置的元素的判断,直接跳到移动的第二位置进行判断。
class Solution {
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--; //if()执行了一次说明找到了删除的元素,数组需要整体向前移动了一次,因此数组大小要减少1
i--; //由于下标i以后的数值都向前移动了一位,所以i也向前移动一位,否则会漏掉对刚往前移动的第一个位置的元素的判断
}
}
return size;
}
}
双指针:使用快指针指向要删除的元素值val的位置,慢指针指向赋值新数组中元素的位置,如果快指针依次遍历指向的位置不是val值,则该位置的值赋值给新数组中慢指针指向的位置元素,此时慢指针才会后移一位;如果快指针依次遍历指向的位置是要删除的val值,那么就不执行if语句内的代码,慢指针此时还停留在原地。这两种情况下快指针的位置是不断后移进行元素值的判断的。
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0;
for(int fast = 0; fast < nums.length; fast++){
if(nums[fast] != val){
nums[slow++] = nums[fast];
}
}
return slow;
}
}