非科班菜鸡算法学习记录 | 代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素。

文章介绍了C++实现的二分查找算法,通过示例代码解释了如何进行系统学习。对于704二分查找问题,作者给出了一次性通过的解决方案。接着,文章讨论了两种删除数组中指定元素的方法,包括暴力解法及其存在的问题和快慢指针优化的解决方案。
摘要由CSDN通过智能技术生成

简单学过C++语法,自己也刷过一些算法题(20来道),但感觉不成系统。这次就从头系统的学一学!

704二分查找

知识点:二分查找     状态:一遍过(可能是因为之前做过有肌肉记忆)

思路: 如果只有一个数,直接比较; 多个数时先用l,r,定义左右边界,每次比较mid=(l+r)/2的数字,如果target>num[mid],移动左边界l到mid+1,用while(l<=r)循环(因为l可以等于r)。

代码:


class Solution {

public:

    int search(vector<int>& nums, int target) 

    {

        int n = nums.size();

        if ( n == 1)

        {

            if ( nums[0] == target )

            {

                return 0;

            }

            return -1;

        }

        else

        {

            int left = 0 , right = n-1 ;

            while ( left <= right )

            {

                int mid = ( left + right ) / 2 ;

                if( nums[mid]  == target)

                {

                    return mid;

                }

                else if ( target < nums[mid]  )

                {

                    right = mid-1;

                }

                else

                {

                    left = mid+1;

                }

            }

            return -1;

        }

    }

};

结果:

27 移除元素

知识点:删除、数组    状态:暴力有小瑕疵;快慢指针看了思路才写出来

方法一 思路: 暴力法,遍历两遍,但此时只对了85/113个。

输入:[0,1,2,2,3,0,4,2]  2   实际输出: [0,1,2,3,0,4]       正确结果:  [0,1,3,0,4]

原因是因为在删除位置2的2后,此时第一个for循环i为2,并将位置3的2移到了位置2,循环结束,i从位置3开始,将第二个数字2跳了过去,导致错误结果。

解决: 因为后边所有数字都往前移了一个位置,所以i也往前移动一个即可

暴力代码:

class Solution {
public:
    int removeElement(vector<int>& nums, int val) 
    {
        int size = nums.size();
        for (int i = 0 ; i <= size-1 ; i++ )
        {
            if ( nums[i] == val )
            {
                for ( int j = i ; j <= size-2 ; j++)
                {
                    nums[j]=nums[j+1];
                }
                --i; // 改正后添加的一行,将i也往前移动一个
                --size;
            }
        }
        return size;
    }
};

 方法二 思路:快慢指针

 right (快指针)为正在遍历的原数组的元素位置,left (慢指针)是指当right 不为 val 的话,将要把right的值插入新数组的位置。(新数组就是在原数组上直接改,while循环结束后,left就是长度)

left就是长度的原因: left指向的是将要插入的位置,是实际插入后的位置+1;而数组长度是最后一个元素位置+1(因为还有一个0位置的元素)。

当循环结束时,left指向的就是最后一个元素位置+1,即数组长度。

代码:

//快慢指针
class Solution {
public:
    int removeElement(vector<int>& nums, int val) 
    {
        int n = nums.size();
        if ( n == 0 )
        {return 0;}

        int left = 0 , right = 0 ; // right (快指针)为遍历数组的元素位置,left (慢指针)是如果right 不为 val 的话,将要插入数组的位置。
        while ( right < n ) // right 遍历到最后跳出循环
        {
            if ( nums[right] == val )
            {
                ++right;
            }
            else
            {
                nums[left] = nums[right] ; 
                ++left;
                ++right;
            }
        }
        return left;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值