Leetcode C++ 《第204场周赛》

前几天再看go语法的时候,发现自己忘记的差不多了,用go刷题的难度又增加了,想学什么还是一鼓作气比较好啦!
这个月的周赛竟然都搞上了,每轮至少2个题目,还算不错hh,虽然因为各种原因没有按时间进行竞赛code~

today is also a beautiful day~

1.题目1

1.1问题

给你一个正整数数组 arr,请你找出一个长度为 m 且在数组中至少重复 k 次的模式。

模式 是由一个或多个值组成的子数组(连续的子序列),连续 重复多次但 不重叠 。 模式由其长度和重复次数定义。

如果数组中存在至少重复 k 次且长度为 m 的模式,则返回 true ,否则返回 false 。

示例 1:

输入:arr = [1,2,4,4,4,4], m = 1, k = 3
输出:true
解释:模式 (4) 的长度为 1 ,且连续重复 4 次。注意,模式可以重复 k 次或更多次,但不能少于 k 次。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/detect-pattern-of-length-m-repeated-k-or-more-times
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

1.2思路
  • 纯暴力的思路,这个easy 题目的难度比之前的有提升,逻辑有点点复杂
  • 找到具体的pattern,然后比对,复杂度大概是nmk
1.3代码
class Solution {
public:
    bool containsPattern(vector<int>& arr, int m, int k) {
        int allLen = m * k;
        if (arr.size() < allLen) {
            return false;
        }
        for (int i = 0; i <= arr.size()-allLen; i++) {
            //pattern [i, i+m-1]
            bool flag = true;
            for (int p = 1; p < k; p++) {
                for (int q = 0; q < m; q++) {
                    if (arr[i+p*m+q] != arr[i+q]) {
                        
                        flag = false;
                        break;
                    }
                }
                if (flag == false)
                    break;
            }
            if (flag)
                return true;
        }
        return false;
    }
};

2.题目2

2.1问题

给你一个整数数组 nums ,请你求出乘积为正数的最长子数组的长度。

一个数组的子数组是由原数组中零个或者更多个连续数字组成的数组。

请你返回乘积为正数的最长子数组长度。

示例 1:

输入:nums = [1,-2,-3,4]
输出:4
解释:数组本身乘积就是正数,值为 24 。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-length-of-subarray-with-positive-product
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2.2思路
  • 动态规划的思路:记录包含i的连续乘积为正的最长长度,包含i的连续乘积为负的最长长度;从而推测i+1的值
  • 为啥要记录负的捏:因为负负得正,负正得负,正正得正【零需要特判】
2.3代码
class Solution {
public:
    int getMaxLen(vector<int>& nums) {
        //包含i,要有正数和负数
        //dp[i][0] 包含i的乘积为正的长度
        //dp[i][1] 为负的长度
        int res = 0;
        int ** dp = new int*[nums.size()];
        for (int i = 0; i < nums.size(); i++) {
            dp[i] = new int[2];
        }
        for(int i = 0; i < nums.size(); i++) {
            if (i == 0) {
                if (nums[i] > 0) {
                    dp[i][0] = 1;
                    dp[i][1] = 0;
                }
                else if (nums[i] < 0) {
                    dp[i][0] = 0;
                    dp[i][1] = 1;
                } else {
                    dp[i][0] = 0;
                    dp[i][1] = 0;
                }      
            } else {
                if (nums[i] > 0) {
                    dp[i][0] = dp[i-1][0]+1;
                    if (dp[i-1][1] == 0) {
                        dp[i][1] = 0;
                    } else 
                        dp[i][1] = dp[i-1][1]+1;
                }
                else if (nums[i] < 0) {
                    dp[i][1] = 1;
                    dp[i][0] = 0;
                    if (dp[i-1][0] != 0) {
                        dp[i][1] = dp[i-1][0]+1; //正负得负
                    }
                    if (dp[i-1][1] != 0) {
                        dp[i][0] = dp[i-1][1]+1; //负负得正
                    }
                } else {
                    dp[i][0] = 0;
                    dp[i][1] = 0;
                }
            }
            //cout << dp[i][0] << " " << dp[i][1] << endl;
            res = max(res, dp[i][0]);
        }
        return res;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值