Leetcode 最小调整数+滑动窗口递增子序列

给定一个长度为N的数组,以及一个乘积值B,每次只能对一个数增大或减少一个单位,问最少多少次使得数组乘积为B

【思路】

要使得调整的次数最少,那么最开始调整的那个数字,应该是最小的数。

贪心策略:选最小的数调整,其它部分数乘积最大(自己需要调整的偏移值就尽可能小)

 

先对原先数组从小到大排序。

对于k  如果 B%k==0  =》  B=B/k   即如果能整除,那么直接整除

如果B%k!=0  =》 不能整除 那么 a[k]--  (即调整一次  因为最差情况下a[k] 调整为1 那么一定能整除)

直到k=>N

int fun(vector<int> arr,int b)
{
    
    int count=0;
    for(int i=0;i<arr.size();i++)
    {
        if(b%arr[i]==0) 
        {
            b/=arr[i];
        }
        else
        {
            arr[i]--;
            count++;
            i--;
        }
    }
    
    
}

 

 

【特殊连续递增序列】

 

给定一个序列,求这样的一个完美序列,是一个连续的子序列,并且序列中每一个数都大于等于前面所有数字之和。 

基本思路:

滑动窗口,left=1 right=1 维护一个sum变量表示窗口中前面k-1个的和:

  • 若当前窗口满足 arr[right]>=sum 那么 更新res     sum+=arr[right]  同时right++ 
  • 若当前窗口不满足  窗口左边缩减             同时    sum-=arr[left]      那么left++

易错点:

原本思路是 add[k]存放前面k个数字之和,那么求解区间直接相减: add[right]-add[left-1]  =》  add会加法溢出

#include<iostream>
#include<vector>
using namespace std;
int main()
{
    int n;
    cin>>n;
    int k;
    for(int i=0;i<n;i++)
    {
        cin>>k;
        vector<long long> arr(k+1,0);
        arr[0]=0;
        //完成初始化
        for(int j=1;j<=k;j++)
            cin>>arr[j];
        int left=1;
        int right=1;
        long long sum=0;  //滑动窗口内之和
        int ans=0;
        while(right<=k)
        {
            if(arr[right]>=sum)  //满足
            {
                ans=max(ans,right-left+1);  //记录下符合要求窗口的长度
                sum+=arr[right];
                right++;  //,满足连续递增
            }
            else
            {
                sum-=arr[left];
                left++;
            }
        }
        cout<<ans<<endl;
    
    }
}

 

 

 

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页