LeetCode第201场周赛总结

题号做出未做
1544
1545
1546
1547

通过率:50%

1544 整理字符串

1545

1546 和为目标值的最大数目不重叠非空子数组数目

问题的本质

    int maxNonOverlapping(vector<int>& nums, int target) {
    ...
    //显然不论如何都是要遍历每一个元素的
        for(auto i : nums){
 			//问题的本质:对于每一个nums中的元素来说,都有且仅有2种选择,要么单独判断是否等于target,要么加上之前的”连续“元素和判断是否等于target。
        }
    ...
    }
 for(auto i : nums){
 }

其实这里有动态规划的思想在里面。即 d p [ i ] dp[i] dp[i]表示下标在[0,i]之间的元素的目标和。则 d p [ i ] dp[i] dp[i]肯定是在 d p [ i − 1 ] dp[i-1] dp[i1]的基础上得到的,但是与 d p [ i − 1 ] dp[i-1] dp[i1]的具体关系要根据 n u m [ i ] num[i] num[i] i i i之前的连续下标的元素和(记为 s u m j sum_{j} sumj)的关系。

  1. 如果存在 j , 使 得 f o r ( i t e m = n u m [ j ] − > n u m [ i ] ) s u m + = i t e m ; s u m = t a r g e t , 则 d p [ i ] = d p [ i − 1 ] + 1 j,使得for(item = num[j] -> num[i]) {sum += item;} sum = target, 则dp[i] = dp[i-1]+1 j使for(item=num[j]>num[i])sum+=item;sum=target,dp[i]=dp[i1]+1;
  2. 否则dp[i] = dp[i-1];

问题的求解思路

解决的关键在于如何实现 f o r ( i t e m = n u m [ j ] − > n u m [ i ] ) s u m + = i t e m ; s u m = t a r g e t , 则 d p [ i ] = d p [ i − 1 ] + 1 for(item = num[j] -> num[i]) {sum += item;} sum = target, 则dp[i] = dp[i-1]+1 for(item=num[j]>num[i])sum+=item;sum=target,dp[i]=dp[i1]+1 。这个问题看上去很复杂,其实非常的简单。小学加减法问题。即 s u m [ x , z ] = s u m [ y , z ] + s u m [ x , y ) , 其 中 x < y < z sum_{[x,z]} = sum_{[y,z]} + sum_{[x,y)},其中x < y < z sum[x,z]=sum[y,z]+sum[x,y),x<y<z,对其变形得 t a r g e t = s u m [ x , z ] − s u m [ x , y ) target = sum_{[x,z]}-sum_{[x,y)} target=sum[x,z]sum[x,y)如果找到了对应的 x , y x,y x,y d p [ i ] = d p [ i − 1 ] + 1 dp[i] = dp[i-1]+1 dp[i]=dp[i1]+1。否则 d p [ i ] = d p [ i − 1 ] dp[i] = dp[i-1] dp[i]=dp[i1]

算法实现

s u m [ x , y ) sum_{[x,y)} sum[x,y)是需要存储的,可选的数据结构有:集合,数组等线性随机存取的数据结构都可。

class Solution {
public:
    int maxNonOverlapping(vector<int>& nums, int target) {
    	int ans = 0, sum = 0;
    	set<int> store_sum_xy;
    	store_sum_xy.insert(0);
    	for(auto &i : nums){
			sum += i;
			if(store_sum_xy.find(sum - target) != store_sum_xy.end()){
				++ans;
				sum = 0;
				store_sum_xy.clear();
			}
			store_sum_xy.insert(sum);
		}
		return ans;
    }
};

1547

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值