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

简单学过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& 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;

        }

    }

};

结果:非科班菜鸡算法学习记录 | 代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素。_第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& 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;
    }
};

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

 方法二 思路:快慢指针

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

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

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

代码:

//快慢指针
class Solution {
public:
    int removeElement(vector& 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;
    }
};

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

你可能感兴趣的:(算法,学习,leetcode)