9月7号 学习算法 二分

   二分里代码随想录有道题  插入元素   我在纠结,比如说4和8之间插入7 

 

那么当while(left<=right)时  应该返回left吧,忽视了前提 当left和right和mid指向同一个数后,返回left,跳出条件是left>right

还有总是忘记随着每一次left和right变化,mid需要放while循环里面 以及比较的是nums[mid]和target的大小,不要直接mid就和target比较了

重要!使用前提:有序、无重复元素(例如单调递增)例题里 求x的平方根(别想着sqrt)

数组get双指针法

双指针用在o(1)删除数组元素

sort使用

(1)int a[10]={9,6,3,8,5,2,7,4,1,0}; for(int i=0;i<10;i++) cout<<a[i]<<endl;

sort(a,a+10);

(2)vector<int>& nums

sort(nums.begin(),nums.end());

(3)对于二维vector数组,若数组名为v,则v.size()是vector相当于v[i][j]中i的大小

​​​​​​​2 ​​​​​​​ 题目:给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

这里等于val一个判断语句;双指针;

slow和fast

for(int fast = 0; fast<nums.size();fast++)

if(nums[fast!=target)

nums[slow++]=nums[fast];   

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

#include <iostream>

#include <vector>

#include <cmath>

using namespace std;

int k[] = {-3,-1,1,2,4};

int t = 0;

vector<int>nums;//注意,这里不能写vector<int>nums(5)默认为0了后面出来也是0

int main()

{

    for(int i = 0;i<5;i++)

    {

        if(k[i]<0)

            k[i]=-k[i];

    }

    sort(k,k+4);//注意这里用法!纠结是+4还是+5;就是结束后往后一位;这是普通数组sort,vector数组sort直接数组名.begin(),数组名.end()

    for(int i = 0;i<5;i++)

    {

        t=pow(k[i],2);

        nums.push_back(t);

    }

    for(int i = 0;i<5;i++)

        cout<<nums[i]<<" ";

}

绝了解法二:​​​​​​​

由于负数的原因,平方大的要么在开头要么在结尾;因此采用双指针,再开一个数组k[]和指针t

t指针指向nums数组末尾

i指向开头,j指向结尾,

if(nums[i]*nums[i]>nums[j]*nums[j])

k[t--]=nums[i]*nums[i]

i--;

if(nums[i]*nums[i]<=nums[j]*nums[j])

k[t--]=nums[j]*nums[j]

​​​​​​​j--;

4 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

纠结1:result = result>sublength ? result : sublength;

//注意这里result=,就把小的已经赋值了

解决方法  引入移动窗口

首先这里需要按照次序,所以别想着排序

1 窗口长度,当窗口里元素之和等于target时,更新

更新方式  

首先一个全局变量result保存最小的那个,一个一直在变disentangle,也就是存储每一次符合要求的元素个数

result = result>disentangle? result:disentangle;

2 维护窗口开始和结束

窗口开始:j = 0 ,i = 0这时不符合等于target的条件,所以累加i

窗口变化:j++ 这时需要一个循环判断while  在j++时一定是循环判断符合》=target的情况的

这时就尝试,i不变化,j往后移动

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

箭头头部开区间,左边开始部分闭区间

1 清楚方向

2 vector数组二维初始化

    vector<vector<int>>a(n,vector<int>(n,0))

3 奇数偶数情况不一样

  相同处: loop也就是转几圈  根据n/2    

 奇数需要额外中间加一个数

注意这里startx 和 starty控制的圈的开始部分,是会随着循环变化的

第一圈startx= 0,第二圈startx = 1

end = 1//这个 第二圈就2了

四个独立循环

for(j = starty;i<n+starty-end;i++)

       res[i][j] = count++//从左到右,出来的时候j满格

这里可能有问题,为什么i和startx两个变量,j随着赋值变化遍历区间元素,startx不能变,因为代表的是区间开始的位置

for(i = startx;i<n+startx-end;j++)

res[i][j] = count++//出来时i满格

for(;j>starty;j--)

for(;i>startx;i--)

这些都是while(loop--)

后如果是奇数:if(n%2) res[n/2][n/2]=count

//后面都是res[i][j]但是第一遍是res[start][j],注意啊,后面的i和j都是变化过的,但数组里刚开始如果将start替换为i,那么第二圈的时候,i位置不对

//特别需要注意!!循环里i和j不要反了,i是平行的,j是竖着的

​​​​​​​//控制区间的end,是每一次往里面缩小个2 ,我第一次写成了end=end+start*2

注意:学自    代码随想录

           如有问题,麻烦指正

​​​​​​​

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值