【日更刷题】1566. 重复至少 K 次且长度为 M 的模式

103 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情

一、题目描述:

1566. 重复至少 K 次且长度为 M 的模式 - 力扣(LeetCode)

给你一个正整数数组 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 次。

示例 2:

输入:arr = [1,2,1,2,1,1,1,3], m = 2, k = 2
输出:true
解释:模式 (1,2) 长度为 2 ,且连续重复 2 次。另一个符合题意的模式是 (2,1) ,同样重复 2 次。

示例 3:

输入:arr = [1,2,1,2,1,3], m = 2, k = 3
输出:false
解释:模式 (1,2) 长度为 2 ,但是只连续重复 2 次。不存在长度为 2 且至少重复 3 次的模式。

示例 4:

输入:arr = [1,2,3,1,2], m = 2, k = 2
输出:false
解释:模式 (1,2) 出现 2 次但并不连续,所以不能算作连续重复 2 次。

示例 5:

输入:arr = [2,2,2,2], m = 2, k = 3
输出:false
解释:长度为 2 的模式只有 (2,2) ,但是只连续重复 2 次。注意,不能计算重叠的重复次数。

提示:

  • 2 <= arr.length <= 100
  • 1 <= arr[i] <= 100
  • 1 <= m <= 100
  • 2 <= k <= 100

二、思路分析:

假定模式长度为m=2,模式{arr[0]arr[1]},此时本模式已经出现了1次,记作tempK=1

判断下一个模式是否相等,就是判断

arr[0]==arr[0+2]?

arr[1]==arr[1+2]?

都相等,tempK++;模式不变,继续向下比较

arr[0+2]==arr[0+2+2]?

arr[1+2]==arr[1+2+2]?

都相等,tempK++;模式不变,继续向下比较

……

直到出现等式不成立 或 数组末尾的模式,此时退出当前模式的处理。

退出当前模式的处理后,对当前模式重复的次数tempK进行处理:

如果满足tempK>=K则不需要对后面的模式进行处理

如果不满足,则处理下一个模式arr[1]arr[2],此时本模式已经出现了1次,记作tempK=1

(重复上述过程)

三、AC 代码:

public boolean containsPattern(int[] arr, int m, int k) {

        //tempK:当前模式重复的次数
        int tempK;

        //因为模式{ arr[length-1-m]~arr[length-1] }
        //这个模式的后方没有其他模式,所以这个模式重复次数为1,因为K>=2
        //所以这个循环应该到arr.length - m结束
        for (int i = 0; i < arr.length-m; i++) {

            //当前模式重复的次数都应该初始为1
            tempK=1;

            //当前模式 与 下一个m长度的模式比较
            //假设m=2也就是arr[0]arr[1]与arr[2]arr[3]比较
            // 之后再让arr[2]arr[3]与arr[4]arr[5]比较 一直比较到最后一个长度为m的模式
            for (int j = i; j < arr.length-m; j=j+m) {
                int l;

                //模式中的每个元素一个一个比较
                for (l = j; l < j+m && l+m<arr.length; l++) {
                    if(arr[l]!=arr[l+m]){
                        break;
                    }
                }

                //如果发生了break,则当前模式与下一模式不匹配
                if(l<j+m){
                    break;
                }

                //否则当前模式重复的次数+1
                tempK++;
            }

            //当前模式的重复次数已经大于等于K
            if(tempK>=k){
                return true;
            }
        }

        //没有任何模式的重复次数大于等于K
        return false;
    }