学习算法第一篇之数组

目录

前言

一、什么是数组

二、数组的使用

1、查找指定的元素(二分查找法)

1.1、问题描述

1.2、解题思路

1.3、实现代码

2、移除数组元素(双指针法)

2.1、问题描述

2.2、解题思路

2.3、实现代码

3、有序数组的平方(双指针)

3.1、问题描述

3.2、解题思路

3.3、实现代码

4、长度最小的子数组(双指针,滑动窗口)

4.1、问题描述

4.2、解题思路

4.3、实现代码

总结


前言

        本篇文章主要是我学习算法的一些总结,便于以后复习,当然能帮助到其他人也很不错。

        我是跟着代码随想录学的,卡尔哥真的很NB,因为是学生党买不起书又不想白嫖,所以我每次看B站视频都会点赞投币,就算是对卡尔哥的一点点感谢吧。

        卡哥的这个算法课是基于数据结构然后在力扣上找了一些经典的题目讲解,会用到一些算法的思想,毕竟程序=数据结构+算法嘛。


一、什么是数组

        百度:一组数据的集合称为数组 Array。补充一下:数组是一种线性的数据结构。

        应该每个学过语言的人对数组都有印象并且会使用这个数据结构,在简单的程序中数组是存储数据的首选,它没有链表、栈、队列、树那些复杂。

二、数组的使用

1、查找指定的元素(二分查找法)

1.1、问题描述

        给定一个有序的数组(默认升序,如果是无序的就要自己排序,十大排序算法我也写了九个在博客中),然后再给一个target值,查找target在数组中的位置。

1.2、解题思路

        数组是有序的,所以直接从中间开始找,判断与target值的大小,target大就往右找,target值小就往左边找,直到不能再二分。

1.3、实现代码

        1、确定左右边界,算出中间值。

        2、确定while循环条件(左边界要小于等于右边界)。

        3、判断该中间值与target的大小关系,改变左右边界。

int search(int* nums, int numsSize, int target){
    int left=0;
    int right=numsSize-1;
    int mid=(left+right)/2;
    while(left<=right)
    {
        mid=(left+right)/2;
        if(target==nums[mid]) 
        {
            return mid;
        }
        if(target>nums[mid]) 
        {
            left=mid+1;
        }
        if(target <nums[mid])
        {
            right = mid-1;
        }
    }
    return -1;
}

2、移除数组元素(双指针法)

2.1、问题描述

        在给定的目标的数组中移除给定target值。

2.2、解题思路

        使用的方法是双指针,这里的指针并不是指针这个数据结构,而是用下标去模拟指向这个元素。

        定义两个指针(fast,slow)和一个新的数组,fast和slow都指针数组的首元素,fast指针遍历目标数组,每次与target进行判断,如果相同就存入新数组中(slow就是新数组的下标)。

2.3、实现代码

        1、使用fast循环遍历数组,判断当前值是否与target相等。

        2、不相等的话就存入新数组,slow++。

int removeElement(vector<int>& nums, int val) {
        int slow = 0;
        int fast = 0;
        int len = nums.size();
        vector<int> temp_num;
        temp_num.assign(nums.begin(),nums.end());
        for(;fast<len;fast++)
        {
            if(temp_num[fast] != val)
            {
                nums[slow++] = temp_num[fast];
            }
        }
        return slow;
    }

3、有序数组的平方(双指针)

3.1、问题描述

        将一个给定的有序数组平方然后再进行值的排序(无序也可以自己排序)。

3.2、解题思路

        本题主要的考点就是负数的平方是正数,可能要比后面的一些正数的平方还大,所以要进行判断不能直接返回原来排序基础上的平方了。

        使用的也是双指针的方法,创建两个指针(一个指向头一个指向尾)和一个新数组,比较两个指针的平方(因为只有头部负数的平方才有机会比尾部最大值的平方大),选择出大的一边存入新的数组,然后将指针往中间移动,直到两个指针错过。

3.3、实现代码

        1、确定数组的front和back,循环条件是front要小于等于back。

        2、比较两者的平方的大小,如果是front大就存入新数组,front往右移。反之则back往左移。

vector<int> sortedSquares(vector<int>& nums) {
        vector<int> temp_array;
        temp_array.assign(nums.begin(),nums.end());
        int index = nums.size() -1 ;
        int front = 0;
        int back = index;
        for(;front<=back;)
        {
            if(pow(temp_array[front],2) >= pow(temp_array[back],2))
            {
                nums[index--] = pow(temp_array[front],2);
                front++;

            }
            else
            {
                nums[index--] = pow(temp_array[back],2);
                back--;
            }
        }
        return nums;
    }

4、长度最小的子数组(双指针,滑动窗口)

4.1、问题描述

        在给定的数组中(没有负数),寻找连续的元素和大于target且长度最小。

4.2、解题思路

        使用双指针(fast,slow)模拟滑动的窗口,窗口的条件就是大于target。

fast和slow都指针数组的首元素,使用fast指针遍历数组,将移动过的元素全部加起来(sum),如果加起来都小于target那说明没有最小的子数组。当fast经过的元素和(sum)大于target时,就移动slow,将前面的sum减去slow元素(目的是为了缩小大于target的范围),如果sum还是大于target那么slow就继续移动,如果sum小于target那么就要继续移动fast寻找其他大于target的范围。

4.3、实现代码

        1、fast遍历数组,每个元素相加sum。

        2、当sum值大于target时,就移动slow指针,缩小范围,寻找最短的区间(fast-slow)。

        3、sum小于target时就继续移动fast。

int minSubArrayLen(int target, vector<int>& nums) {
        int slow = 0;
        int fast = 0;
        int sum = 0;
        int result = nums.size();
        int temp_res = 0;
        int len = nums.size();
        for(;fast<len;fast++)
        {
            sum += nums[fast];
            while(sum>=target)
            {
                temp_res = fast - slow + 1;
                result = min(result,temp_res);
                sum -= nums[slow++];   
            }
        }
        result = min(result,temp_res);
        return result;
    }

总结

       给的代码是我在力扣上通过的,基本上都是看完卡哥视频之后写的,代码基本完全一致哈哈,主要是要学会这些解题的思想。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hard-coding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值