• 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);
    }
    
  • 相关阅读:
    SpringBoot系列之缓存使用教程
    Dubbo系列之常用配置用法简介
    SpringBoot系列之集成Dubbo的方式
    JavaScript系列之回调函数callback
    JavaScript系列之事件冒泡机制简介
    Oracle基础之保留字和关键字
    Oracle调优之no_unnest和unnest用法简介
    InnoSetup 以命令行自动编译打包
    InnoSetup 脚本打包及管理员权限设置
    C# 获取系统当前IE版本号
  • 原文地址:https://www.cnblogs.com/fyusac/p/14843984.html
Copyright © 2020-2023  润新知