因为这两天考试加上颈椎突然出问题了,打卡拖了几天时间。
数组二分查询
二分查询之前自己写过,但蛮长时间没有刷过算法题了,很多java基础代码都有点模糊
我选择的是左闭右闭写法,一开始我按照记忆中写出的while循环条件是left<right,但是测试中显示无法同意数组长度为一的情况,分析了一下是的,因为right=nums.length-1我这样直接就把数组为一的情况拒绝了他的循环,然后循环条件就改成了left<=right。
整体思路:将有序数组分为两半,如果目标值大于数组中间值,就查询左半边,目标值小于中间值就查询右半边。
- 取left=0,right=nums.length-1。
- middle放进循环中再取=left+(right-left)/2。这样做可以一行代码满足目标值在左半边和右半边两种情况,减少代码量
- 比较目标值和nums[middle],目标值大于nums[middle]就去右半边,小于就去左半边,等于就返回下标,退出循环。
- while结束后返回-1表示没有找到
class Solution {
public int search(int[] nums, int target) {
if(target<nums[0] || target>nums[nums.length-1])
return -1;
int left=0;
int right=nums.length-1;
while(left<=right){
int middle=(right-left)/2+left;
if(nums[middle]==target)
return middle;
else if (nums[middle]>target)
right=middle-1;
else
left=middle+1;
}
return -1;
}
}
移除元素-快慢指针
做到移除元素这个题的时候,题目中给出的是移除元素后的数组长度可以不变,确保要被移除的元素在数组最后即可。所以一开始的思路是双向指针,一个指针在前往后,一个从后往前,前面的那个遇到要被移除的元素就停,后面那个遇到不是被移除的元素就停,然后两者交换。但是实际代码处理过程中需要考虑到数组长度为1且该元素就是要被移除的元素以及使用循环的时候,循环条件的设置和指针值不能<0的情况,导致修改了很多次依然没能通过全部测试案例。
然后就修改了思路,转换为快慢指针的想法。但是也遇到了一些问题,看题解代码也没有理解,后来看了视频恍然大悟。整体思路:块、慢指针一开始都指向0,快指针循环加1,如果快指针指向的数组元素不是要被移除的元素,就让慢指针指向位置的元素值等于该快指针指向的元素值,然后慢指针也加一。
- 取fast,slow为0,进入while(fast<nums.length)循环中,即当快指针遍历完数组就结束
- 当fast指针指向的不是要被移除的元素就让慢指针所指的位置元素值改为快指针当前所指元素值。
- 就相当于是把n个元素中不是要被移除的元素的m个元素放到前m个位置
- 注意:m个元素后面的不用考虑,还是保持原始数组样式即可,因为你已经拿到了m个不需要移除的元素,修改数组长度或者赋值给新数组都可。
class Solution {
public int removeElement(int[] nums, int val) {
int fast=0;
int slow=0;
while(fast<nums.length){
if(nums[fast]!=val){
nums[slow]=nums[fast];
slow++;
}
fast++;
}
return slow;
}
}