题目链接:704.二分查找
在真正做本题之前,我已经有了一定基础,对于二分查找的概念和整体思路已经有了大概的认识。不过在没有看过carl哥之前,没有一个完整的做题流程和顺序,就是想到什么写什么,如果发现缺少了某些变量再补上。在没有看carl的视频之前,关于left跟right指针应该怎么更新一直存在着疑惑,因为实际写题的过程中会发现对于两边指针的处理不仅仅是将middle值进行覆盖这么简单,有的还需要进行-1或者+1。
在看过carl的视频过后,终于明白了本人为何会一直纠结指针的更新,原因就在于并没有确立查找的边界,通过carl的讲解,个人认为后面left跟right的更新以及while的循环条件的确立在于查找边界的确定。视频中carl详细讲解了左闭右闭和左闭右开的具体写法以及思路,个人充分理解后,想将左开右闭的代码写出来,期间遇到了不少困难,不过最终ac,代码如下:
class Solution {
public int search(int[] nums, int target) {
int n=nums.length;
int left=-1;
int right=n-1;
while(right>left){
int middle=(left+right+1)/2;
if(nums[middle]<target){
left=middle;
}else if(nums[middle]>target){
right=middle-1;
}else{
return middle;
}
}
return -1;
}
}
因为这段代码是在本人写完前两种写法后再思考出来的,因此并没有在代码段上做任何注释。细心看我的代码会发现,我对于middle的处理做了一个跟前两种方法截然不同的操作,前两种方法中middle=(left+right)/2,而在左开右闭这里我对双指针下标相加后还进行了一个+1的操作,原因在于系统本身除法的运算规则是向下取整,在个人的debug过程中就发现遵循原有的运算规则情况下,当查找的值在(i,i+1]区间时,middle的值会一直被赋予为i,因此按照第一个if语句判断后会无限循环卡在这个区间,因此我们需要改变原有的运算规则进行向上取整,进行+1的操作。
以下是前两种方法的代码:
class Solution {
public int search(int[] nums, int target) {
int n=nums.length;
int left=0;
int right=n-1;
while(left<=right){
int middle=(left+right)/2;
if(nums[middle]<target){
left=middle+1;
}else if(nums[middle]>target){
right=middle-1;
}else{
return middle;
}
}
return -1;
}
}
class Solution {
public int search(int[] nums, int target) {
int n=nums.length;
int left=0;
int right=n;
while(left<right){
int middle=(left+right)/2;
if(nums[middle]<target){
left=middle+1;
}else if(nums[middle]>target){
right=middle;
}else{
return middle;
}
}
return -1;
}
}
题目链接:leetcode 27.移除元素
本题要求对原数组进行修改,数组不能进行数据的删除只能进行数据的覆盖。
首先想到的就是暴力嘛,毕竟这是一个简单的题目,找到跟val值后移动到末尾然后val值后的所有元素前移,需要两层for循环,一层便利数组,一层进行数据的移动。
但是对于一道简单的题目来说,我的关注点就不是ac了,而是有无更优的解法,暴力的时间复杂度为n方,本题的要求实质上就是不是val值的跟val值位置交换,按照这个逻辑,如果能够同时记录非val值和val值的位置然后进行交换,则理论上只需要遍历一次数组。因此,带着这个思考看了carl的视频后,使用了双指针(快慢指针)的方法,代码如下:
class Solution {
public int removeElement(int[] nums, int val) {
int fastNode=0;
int slowNode=0;
int n=nums.length;
while(fastNode<n){
if(nums[slowNode]==val&&nums[fastNode]!=val){
int change=nums[slowNode];
nums[slowNode]=nums[fastNode];
nums[fastNode]=change;
++slowNode;
}
if(nums[slowNode]!=val){
++slowNode;
}
++fastNode;
}
return slowNode;
}
}
这两道题是我前两天开始看代码随想录就做了,今天得去拜山,因此只是回顾了一遍当时自己的做题思路,争取晚上继续跟着代码随想录再做几题。