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

it2025-01-20  15

给定一个长度为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; } }

 

 

 

最新回复(0)