代码随想录第一天(数组)

一、数组基础

        1.数组是连续的内存空间,故而可以用下标直接访问。o(1)时间复杂度

        2.当删除元素时,只能将其之后的元素提前,将删除元素覆盖(连续的内存空间,内存不会改变)

        3.常用的解题方法:快慢指针、左右指针等等

二、二分查找

        给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

        解题思路:有序数组 查找元素 —可采用二分查找 左右双指针

        注意事项:循环不变量:左闭右开或左开右闭的区间 一次循环后区间减半

       1. 当为左闭右开时,右指针的元素不包括在区间内,故而循环条件为left<right(保证区间内有元素);其次,初始区间应包括所有元素,故而初始右指针指向最后一个元素的下一位;每次移动右指针时,因为右指针不包括在区间内,故而可令right = mid(区间内并没有mid所指元素)

        2.当为左闭右闭时,左右指针的元素包括在区间内,故而循环条件为left<=right(保证区间内有元素);其次,初始区间应包括所有元素,故而初始右指针指向最后一个元素;每次移动右指针时,因为右指针包括在区间内,故而可令right = mid-1

三、移除元素

        题目:给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

        思路:数组为连续内存,故而元素只能覆盖。因数组元素的顺序可改变—可采用双指针(快慢或左右)

        左右指针:注意变更左右指针时,要判断两者不能越位

  //首尾指针
        int last = nums.size()-1;
        int head = 0;
        while(head<=last){
            if(nums[head]==val){//首指针指向目标元素时
                while(nums[last]==val){//反向遍历,直到尾指针指向非目标元素
                    last--;
                    if(last<head) return head;//右指针不能超过左指针,超过时说明要赋值给左指针,可以直接返回head
                }
                nums[head]=nums[last];
                last--;
            }
            head++;
        }

        return head;
       
    }

四、有序数组的平方

        题目:给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

        思路:有序数组 有正有负 当平方后最大值一定在两侧,只需比较两侧的大小将大的取出,之后在比较两侧即可——采用左右指针

        

vector<int>new2(nums.size(),0);//新数组
        int left=0;
        int right=nums.size()-1;
        int new_right=new2.size()-1;
        while(new_right>=0){
            if(nums[left]*nums[left] < nums[right]*nums[right]){
                new2[new_right]=nums[right]*nums[right];
                right--;
            }
            else{
                new2[new_right]=nums[left]*nums[left];
                left++;
            }
             new_right--;
        }
        return new2;

五、长度最小的子数组

        题目:给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

        思路:大于等于target的最小连续子数组,数组元素不可乱,需要计算算元素之和,并记录数组长度——采用左右指针(移动窗口法),指定区间,区间内之和大于target时,循环移动左指针,直到小于target,记录最小元素数;依次移动窗口,记录最小的元素数。

六、螺旋矩阵

        题目:给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。

        思路:依次循环每一边,按照次序赋值即可、

        注:循环不变量:每一边的首尾指针的区间应一致(左闭右开);每循环一圈,左右指针的起始位置要更新,首尾指针的区间也要更新

 nums = [[0] * n for _ in range(n)]#生成三行三列的矩阵
        zero = n/2
        startx = 0  #起始x
        starty = 0  #起始y
        
        offset = 1  #每一边的终止条件
        count = 1

        while zero > 0:
            i = startx  #每一圈刚开始,要确定起始点的位置
            j = starty  

            while j < n - offset: #每循环一圈,左右两侧未赋值的列分别向里缩进一列
                nums[i][j] = count
                count += 1
                j += 1

            while i < n-offset:
                nums[i][j] = count
                count += 1
                i += 1

            while j > starty:
                nums[i][j] = count
                count += 1
                j -= 1

            while i > startx:
                nums[i][j] = count
                count += 1
                i -= 1

            startx += 1
            starty += 1
            offset += 1
            zero -= 1

        if n%2 != 0:
            nums[n/2][n/2] = count
        
        return nums

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值