diff --git a/docs/0000-00-note.adoc b/docs/0000-00-note.adoc index e0240b14fc..470dab95e1 100644 --- a/docs/0000-00-note.adoc +++ b/docs/0000-00-note.adoc @@ -2,3 +2,9 @@ . xref:0215-kth-largest-element-in-an-array.adoc[215. Kth Largest Element in an Array] 没想到快速排序的分区算法,竟然可以用于做快速选择?!神奇… 可惜的是,这题目以前做过,现在都给忘完了… . xref:0437-path-sum-iii.adoc[437. Path Sum III] 前缀和的解法还需要再思考思考! + +== 解题技巧 + +. 树形 DP 套路 +. 前缀和 +.. xref:0523-continuous-subarray-sum.adoc[523. Continuous Subarray Sum] diff --git a/docs/0523-continuous-subarray-sum.adoc b/docs/0523-continuous-subarray-sum.adoc index de0b32f02f..70b1f44aaa 100644 --- a/docs/0523-continuous-subarray-sum.adoc +++ b/docs/0523-continuous-subarray-sum.adoc @@ -1,3 +1,4 @@ +[#0523-continuous-subarray-sum] = 523. Continuous Subarray Sum https://leetcode.com/problems/continuous-subarray-sum/[LeetCode - Continuous Subarray Sum] @@ -33,6 +34,24 @@ Given a list of *non-negative* numbers and a target *integer* k, write a functio . You may assume the sum of all the numbers is in the range of a signed 32-bit integer. +== 解题分析 + +利用同余定理: + +image::images/0523-01.png[] + +当 latexmath:[prefixSums[q\]−prefixSums[p\]] 为 latexmath:[k] 的倍数时,latexmath:[prefixSums[p\]] 和 latexmath:[prefixSums[q\]] 除以 latexmath:[k] 的余数相同。(_D瓜哥注:余数相同,则相减之后余数就被减掉了。_)因此只需要计算每个下标对应的前缀和除以 latexmath:[k] 的余数即可,使用哈希表存储每个余数第一次出现的下标。 + +image::images/0523-02.png[] + +image::images/0523-03.png[] + +image::images/0523-04.png[] + +image::images/0523-05.png[] + +image::images/0523-06.png[] + [[src-0523]] diff --git a/docs/images/0523-01.png b/docs/images/0523-01.png new file mode 100644 index 0000000000..a66fe3a095 Binary files /dev/null and b/docs/images/0523-01.png differ diff --git a/docs/images/0523-02.png b/docs/images/0523-02.png new file mode 100644 index 0000000000..7e8bf5e4cc Binary files /dev/null and b/docs/images/0523-02.png differ diff --git a/docs/images/0523-03.png b/docs/images/0523-03.png new file mode 100644 index 0000000000..fe7a456339 Binary files /dev/null and b/docs/images/0523-03.png differ diff --git a/docs/images/0523-04.png b/docs/images/0523-04.png new file mode 100644 index 0000000000..a2b23d1f42 Binary files /dev/null and b/docs/images/0523-04.png differ diff --git a/docs/images/0523-05.png b/docs/images/0523-05.png new file mode 100644 index 0000000000..44dcce60a6 Binary files /dev/null and b/docs/images/0523-05.png differ diff --git a/docs/images/0523-06.png b/docs/images/0523-06.png new file mode 100644 index 0000000000..f1147a99d9 Binary files /dev/null and b/docs/images/0523-06.png differ diff --git a/src/main/java/com/diguage/algorithm/leetcode/_0110_BalancedBinaryTree_21.java b/src/main/java/com/diguage/algorithm/leetcode/_0110_BalancedBinaryTree_21.java index e68ced7a84..913db67f00 100644 --- a/src/main/java/com/diguage/algorithm/leetcode/_0110_BalancedBinaryTree_21.java +++ b/src/main/java/com/diguage/algorithm/leetcode/_0110_BalancedBinaryTree_21.java @@ -10,7 +10,7 @@ * * https://leetcode.com/problems/balanced-binary-tree/[LeetCode - Balanced Binary Tree] * - * @author D瓜哥, https://www.diguage.com/ + * @author D瓜哥 · https://www.diguage.com * @since 2020-02-06 23:10 */ public class _0110_BalancedBinaryTree_21 { diff --git a/src/main/java/com/diguage/algorithm/leetcode/_0523_ContinuousSubarraySum.java b/src/main/java/com/diguage/algorithm/leetcode/_0523_ContinuousSubarraySum.java new file mode 100644 index 0000000000..e9e1d18ce1 --- /dev/null +++ b/src/main/java/com/diguage/algorithm/leetcode/_0523_ContinuousSubarraySum.java @@ -0,0 +1,45 @@ +package com.diguage.algorithm.leetcode; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author D瓜哥 · https://www.diguage.com + * @since 2024-06-23 00:23:40 + */ + +public class _0523_ContinuousSubarraySum { + /** + * 参考 https://leetcode.cn/problems/continuous-subarray-sum/solutions/807930/lian-xu-de-zi-shu-zu-he-by-leetcode-solu-rdzi/[523. 连续的子数组和 - 官方题解^] + */ + public boolean checkSubarraySum(int[] nums, int k) { + if (nums == null || nums.length < 2) { + return false; + } + Map remainderToIndexMap = new HashMap<>(); + // 当 sum=0 时,还没有任何数字参与,所以是 -1 + remainderToIndexMap.put(0, -1); + int remainder = 0; + for (int i = 0; i < nums.length; i++) { + // 同余定理 + remainder = (remainder + nums[i]) % k; + if (remainderToIndexMap.containsKey(remainder)) { + int prevIndex = remainderToIndexMap.get(remainder); + if (i - prevIndex >= 2) { + return true; + } + } else { + // 前面已经判断过是否包含该值, + // 这里也就不需要为了保存最小的下标去判断是否已经存在该值 + remainderToIndexMap.put(remainder, i); + } + } + return false; + } + + public static void main(String[] args) { + _0523_ContinuousSubarraySum solution = new _0523_ContinuousSubarraySum(); + boolean result = solution.checkSubarraySum(new int[]{5, 0, 0, 0}, 3); + System.out.println(result); + } +}