代码随想录算法训练营day1|leetcode704二分查找、27移除元素

原题链接:leetcode704二分查找

第一次运行显示出现了函数的返回绘制路径有错误,我只能表示无奈,因为C++基本语法问题真的好多不清楚,没辙,只能一点点补。

【初次题解思路】根据以前学过的二分法,从1/2数组元素处开始出发,判断是否与目标值相等,相等返回下标,不相等进入第二重判断,如果大于目标值,则当前的下标在目标值右侧,向左移动1/2的下标路程,如果小于则向右移动至i+i/2下标处。限制条件为i<10000;

【收获1】使用二分法查找的前提:

1.数组为有序数组;

2.数组中无重复元素;

【收获2】

vector&nums

vector是一个容器,它的底层原理也是数组。所以对数组的一些功能函数也可以用在nums上。

【收获3】二分法求解思路分两种,两种方法存在些微的区别,原理相同。

1.左闭右开[left,right],更新后的区间不包括更新前的middle,因为在前一次的判断中已经将其包括在内。

2.左闭右开[left,right]更新后的区间包括更新前的middle

int right=nums.size();

int middle=left+((right-left)>>1);

先定义一个left=0,作为左侧下标值,right=nums.length()+1作为右侧下标。初次查找范围是整个数组,每次查找范围[left,right]的中值,相等就直接返回下标right,不相等就向左右最大子区间的mid值进行移动,即让right=1/2*(left+right),或者让right=right+1/2*(right-left),如此不断实现一次次的移动,使查找范围变为原来的1/2,1/2的1/2,1/2的1/4……直到找到目标值target,返回当前的下标right,也就是mid的值,如果查找范围·已经到了边界,还没有找到,那么target不在所给的数组中,结束查询后返回值为-1.

左右下表都是有可能移动的,如果当前的mid大于或等于target,就表明target在当前的[left,mid]中,就让right=mid;反之,如果mid小于等于target,则表示target在[mid,right]中,就使left=mid;

接着进入下一轮的判断和数组更新。

下面是求解的源代码:

class Solution {
public:
    int search(vector& nums, int target) {
int left=0,right=nums.size()-1;
while(left<=right)
{
    int mid=(right-left)/2 + left;
    int num=nums[mid];
    if(num==target)
    {return mid;}
    else if(num>target)
    {
        right = mid - 1;
    }
         else {
             left = mid + 1;
         }

}
return -1;
    }
};

【收获4】

在第一次的求解中,用到了for写循环,在返回值这里出现了问题

在写循环时,以往我习惯使用for,除了for循环还有其他的循环结构,比如这道题用到的:

while(left<=right)
{
}
%只要左侧的索引是小于等于右侧的索引就执行循环,直到不满足这个条件

【收获5】涉及到移位的运算

int middle = left +((right-left)>>1);

原题链接leetcode27移除元素

第一次求解中,报错原因是返回值没写,准确说不知道返回值是什么了,题目给出的返回方式有点没看明白。用了循环检索出和目标val相等的数组元素,nums[i],然后用下一个nums[i+1]覆盖掉nums[i],利用第二重循环,把后面的把前面的依次覆盖掉。

for(int i;i

暴力求解:

class Solution {
public:
    int removeElement(vector& nums, int val) {
   int size=nums.size();
   for(int i=0;i

【收获1】容器vector不能使用nums.length(),但是可以使用nums.size()

【收获2】同向双指针法删除元素

定义两个指针,快指针用来寻找目标val;慢指针用来指向更新,新数组下标的位置

先定义一个慢指针

int slowIndex = 0;

用一个快指针检索出val,如果这个nums[fastIndex]不是val,就让慢指针指向这个新的数组元素

for( int fastIndex = 0 ; fastIndex < nums.size() ; fastIndex++)
{
  if( val != nums[fastIndex] )
	{ nums[slowIndex++] = nums[fastIndex] ;
	}
	
}

这种求解方法的源代码:

class Solution {
public:
    int removeElement(vector& nums, int val) {
int slowIndex=0;
for(int fastIndex=0;fastIndex

【收获3】

双向双指针求解左右开弓,尽量让更少的元素移动,这种解法相当于对上一种元素的优化。

如果做指针left指向的元素等于val,此时将右指针right指向的元素复制大左指针left的位置,然后右指针right左移一位,如果赋值过来的元素恰好也等于val,可以继续把右指针right指向的元素赋值过来(左指针left指向的等于val的元素的位置继续被覆盖),直到左指针指向的元素的值不等于val为止。

当左指针与右指针重合时,左右指针遍历完数组中的元素。

求解源代码:

class Solution {
public:
    int removeElement(vector& nums, int val) {
    int left = 0,right = nums.size();
    while(left < right){
        if(nums[left]==val){
            nums[left]=nums[right-1];
            right--;

        }else {
            left++;
        }
    }
    return left;
    }
};

你可能感兴趣的:(代码随想录算法训练营,算法基础,数据结构,算法,leetcode,c++)