leetcode 523 连续的子数组和

Posted 枫叶艾辰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode 523 连续的子数组和相关的知识,希望对你有一定的参考价值。

package com.example.lettcode.dynamicprogramming;

import java.util.HashSet;
import java.util.Set;

/**
 * @Class CheckSubarraySum
 * @Description 523 连续的子数组和
 * 给你一个整数数组 nums 和一个整数 k ,编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组:
 * (1)子数组大小 至少为 2 ,且
 * (2)子数组元素总和为 k 的倍数。
 * 如果存在,返回 true ;否则,返回 false 。
 * 如果存在一个整数 n ,令整数 x 符合 x = n * k ,则称 x 是 k 的一个倍数。
 * <p>
 * 示例 1:
 * 输入:nums = [23,2,4,6,7], k = 6
 * 输出:true
 * 解释:[2,4] 是一个大小为 2 的子数组,并且和为 6 。
 * 示例 2:
 * 输入:nums = [23,2,6,4,7], k = 6
 * 输出:true
 * 解释:[23, 2, 6, 4, 7] 是大小为 5 的子数组,并且和为 42 。
 * 42 是 6 的倍数,因为 42 = 7 * 6 且 7 是一个整数。
 * 示例 3:
 * 输入:nums = [23,2,6,4,7], k = 13
 * 输出:false
 * @Author
 * @Date 2021/6/2
 **/
public class CheckSubarraySum {

    /**
     * DP
     * Memory Limit Exceeded
     *
     * @param nums
     * @param k
     * @return
     */
    public static boolean checkSubarraySum01(int[] nums, int k) {
        if (nums == null || nums.length == 0 || k == 0) return false;

        int len = nums.length;
        int[][] dp = new int[len][len];
        for (int i = 0; i < len; i++) {
            dp[i][i] = nums[i];
        }

        for (int i = 0; i < len - 1; i++) {
            for (int j = i + 1; j < len; j++) {
                dp[i][j] = dp[i][j - 1] + nums[j];
                if (dp[i][j] % k == 0) return true;
            }
        }
        return false;
    }

    /**
     * 前缀和 + 哈希
     *
     * @param nums
     * @param k
     * @return
     */
    public static boolean checkSubarraySum(int[] nums, int k) {
        if (nums == null || nums.length == 0 || k == 0) return false;

        int n = nums.length;
        int[] sum = new int[n + 1];
        for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + nums[i - 1];
        Set<Integer> set = new HashSet<>();
        for (int i = 2; i <= n; i++) {
            // 子数组长度至少有两个元素
            set.add(sum[i - 2] % k);
            // set.contains(sum[i] % k)为true ,说明从sum[i]-sum[j]是k的倍数
            if (set.contains(sum[i] % k)) return true;
        }
        return false;
    }
}
// 测试用例
public static void main(String[] args) {
	int[] nums = new int[]{23, 2, 4, 6, 7};
	int k = 6;
	boolean ans = CheckSubarraySum.checkSubarraySum(nums, k);
	System.out.println("CheckSubarraySum demo01 result : " + ans);

	nums = new int[]{23, 2, 6, 4, 7};
	k = 6;
	ans = CheckSubarraySum.checkSubarraySum(nums, k);
	System.out.println("CheckSubarraySum demo01 result : " + ans);

	nums = new int[]{23, 2, 6, 4, 7};
	k = 13;
	ans = CheckSubarraySum.checkSubarraySum(nums, k);
	System.out.println("CheckSubarraySum demo01 result : " + ans);
}

以上是关于leetcode 523 连续的子数组和的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode523. 连续的子数组和

leetcode No.523 连续的子数组和 java

leetcode中等523连续的子数组和

LeetCode每日一题——523. 连续的子数组和(同余定理)

LeetCode523. 连续的子数组和/394. 字符串解码/牛客:万万没想到之抓捕孔连顺

LeetCode 523 连续的子数组和[前缀和 哈希表] HERODING的LeetCode之路