diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 20f53706..cc3f6fb8 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -123,6 +123,7 @@ - [0401-0500](leetcode/orders/0401-0500.md) - [0485. 最大连续1的个数 Max Consecutive Ones](leetcode/0485.max-consecutive-ones/index.md) - [0501-0600](leetcode/orders/0501-0600.md) + - [0532.数组中的数对 K-diff Pairs in an Array](leetcode/0532.k-diff-pairs-in-an-array/index.md) - [0601-0700](leetcode/orders/0601-0700.md) - [0680. 验证回文串 II Valid Palindrome II](leetcode/0680.valid-palindrome-ii/index.md) - [0701-0800](leetcode/orders/0701-0800.md) diff --git a/src/leetcode/0349.intersection-of-two-arrays/index.md b/src/leetcode/0349.intersection-of-two-arrays/index.md index ad352fd0..4656e41f 100644 --- a/src/leetcode/0349.intersection-of-two-arrays/index.md +++ b/src/leetcode/0349.intersection-of-two-arrays/index.md @@ -2,7 +2,7 @@ [问题描述](../problems/0349.intersection-of-two-arrays/content.html) -这个问题的解法就比较多了. +这是一个搜索问题, 这个问题的解法就比较多了. ## 并行双指针 @@ -75,4 +75,4 @@ C++ 这样的语言在标准库里自带了 BitSet, 但在 Rust 标准库里却 ## 相关问题 -- [0350. 两个数组的交集 II Intersection of Two Arrays II](../0350.intersection-of-two-arrays-ii/index.md) \ No newline at end of file +- [0350. 两个数组的交集 II Intersection of Two Arrays II](../0350.intersection-of-two-arrays-ii/index.md) diff --git a/src/leetcode/0532.k-diff-pairs-in-an-array/Cargo.toml b/src/leetcode/0532.k-diff-pairs-in-an-array/Cargo.toml new file mode 100644 index 00000000..9aadd7b1 --- /dev/null +++ b/src/leetcode/0532.k-diff-pairs-in-an-array/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "lc-0532-k-diff-pairs-in-an-array" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] diff --git a/src/leetcode/0532.k-diff-pairs-in-an-array/index.md b/src/leetcode/0532.k-diff-pairs-in-an-array/index.md new file mode 100644 index 00000000..a770b02e --- /dev/null +++ b/src/leetcode/0532.k-diff-pairs-in-an-array/index.md @@ -0,0 +1,3 @@ +# 0532.数组中的数对 K-diff Pairs in an Array + +[问题描述](../problems/0532.k-diff-pairs-in-an-array/content.html) diff --git a/src/leetcode/0532.k-diff-pairs-in-an-array/src/main.rs b/src/leetcode/0532.k-diff-pairs-in-an-array/src/main.rs new file mode 100644 index 00000000..9ca417d8 --- /dev/null +++ b/src/leetcode/0532.k-diff-pairs-in-an-array/src/main.rs @@ -0,0 +1,208 @@ +// Copyright (c) 2024 Xu Shaohua . All rights reserved. +// Use of this source is governed by General Public License that can be found +// in the LICENSE file. + +use std::collections::{HashMap, HashSet}; + +// 哈稀表 +pub fn find_pairs1(nums: Vec, k: i32) -> i32 { + assert!(!nums.is_empty()); + + let mut map = HashMap::new(); + for num in &nums { + map.entry(num).and_modify(|count| *count += 1).or_insert(1); + } + + let mut set = HashSet::new(); + for &num in &nums { + // k = diff - num; + // diff1 >= num + let diff1 = num + k; + if let Some(count) = map.get(&diff1) { + if diff1 > num { + set.insert(vec![num, diff1]); + } else if diff1 == num { + if *count > 1 { + set.insert(vec![num, diff1]); + } + } + } + + // k = num - diff; + // diff2 <= num + let diff2 = num - k; + if let Some(count) = map.get(&diff2) { + if diff2 < num { + set.insert(vec![diff2, num]); + } else if diff2 == num { + if *count > 1 { + set.insert(vec![num, diff2]); + } + } + } + } + + set.len() as i32 +} + +// 二分查找 +pub fn find_pairs2(nums: Vec, k: i32) -> i32 { + assert!(!nums.is_empty()); + + // 先排序 + let mut nums = nums; + nums.sort(); + let mut set = HashSet::new(); + + for i in 0..(nums.len() - 1) { + let val = nums[i] + k; + if let Ok(_val_index) = nums[i + 1..].binary_search(&val) { + set.insert((nums[i], val)); + } + } + + set.len() as i32 +} + +// 快慢型双指针 +pub fn find_pairs3(nums: Vec, k: i32) -> i32 { + assert!(!nums.is_empty()); + + // 先排序 + let mut nums = nums; + nums.sort(); + + let mut fast = 0; + let len = nums.len(); + let mut count = 0; + + // 遍历数组 + while fast < len { + let curr_val = nums[fast]; + let expected_val = curr_val + k; + // 当前值和期待值是否相等, 即 k 是否为0. + if expected_val == curr_val { + // 只保留两个重复元素, 跳过其它的. + let mut added = false; + while fast + 1 < len && curr_val == nums[fast + 1] { + if !added { + count += 1; + added = true; + } + fast += 1; + } + } else { + // 跳过所有重复元素 + while fast + 1 < len && curr_val == nums[fast + 1] { + fast += 1; + } + // 使用二分查找法在后面的元素里搜索 `expected_val`. + if fast + 1 < len && nums[fast + 1..].binary_search(&expected_val).is_ok() { + count += 1; + } + } + + // 指针向前走一步 + fast += 1; + } + + count +} + +// 根据 k == 0 做优化 +pub fn find_pairs4(nums: Vec, k: i32) -> i32 { + assert!(!nums.is_empty()); + + // 先排序 + let mut nums = nums; + nums.sort(); + let mut count = 0; + let mut fast = 0; + + if k == 0 { + let len = nums.len(); + + // 遍历数组 + while fast < len { + let curr_val = nums[fast]; + // 只保留两个重复元素, 跳过其它的. + if fast + 1 < len && curr_val == nums[fast + 1] { + count += 1; + fast += 1; + } + while fast + 1 < len && curr_val == nums[fast + 1] { + fast += 1; + } + + // 指针向前走一步 + fast += 1; + } + } else { + // 去掉重复元素 + nums.dedup(); + let len = nums.len(); + + // 遍历数组 + while fast < len { + let curr_val = nums[fast]; + let expected_val = curr_val + k; + // 使用二分查找法在后面的元素里搜索 `expected_val`. + if fast + 1 < len && nums[fast + 1..].binary_search(&expected_val).is_ok() { + count += 1; + } + + // 指针向前走一步 + fast += 1; + } + } + + count +} + +pub type SolutionFn = fn(Vec, i32) -> i32; + +fn check_solution(func: SolutionFn) { + let nums = vec![3, 1, 4, 1, 5]; + let k = 2; + assert_eq!(func(nums, k), 2); + + let nums = vec![1, 2, 3, 4, 5]; + let k = 1; + assert_eq!(func(nums, k), 4); + + let nums = vec![1, 3, 1, 5, 4]; + let k = 0; + assert_eq!(func(nums, k), 1); +} + +fn main() { + check_solution(find_pairs1); + check_solution(find_pairs2); + check_solution(find_pairs3); + check_solution(find_pairs4); +} + +#[cfg(test)] +mod tests { + use super::{check_solution, find_pairs1, find_pairs2, find_pairs3, find_pairs4}; + + #[test] + fn test_find_pairs1() { + check_solution(find_pairs1); + } + + #[test] + fn test_find_pairs2() { + check_solution(find_pairs2); + } + + #[test] + fn test_find_pairs3() { + check_solution(find_pairs3); + } + + #[test] + fn test_find_pairs4() { + check_solution(find_pairs4); + } +} diff --git a/src/leetcode/tags/binary-search.md b/src/leetcode/tags/binary-search.md index 3256a9a9..d2b28ade 100644 --- a/src/leetcode/tags/binary-search.md +++ b/src/leetcode/tags/binary-search.md @@ -2,6 +2,10 @@ ## 容易 +1. [0349. 两个数组的交集 Intersection of Two Arrays](../0349.intersection-of-two-arrays/index.md) + +TODO: + - [69. x 的平方根](https://leetcode.com/problems/sqrtx) - [167. 两数之和 II - 输入有序数组](https://leetcode.com/problems/two-sum-ii-input-array-is-sorted) - [278. 第一个错误的版本](https://leetcode.com/problems/first-bad-version) @@ -16,6 +20,11 @@ ## 中等 +1. [0167. 两数之和 II - 输入有序数组 Two Sum II - Input Array Is Sorted](../0167.two-sum-ii-input-array-is-sorted/index.md) +2. [0532.数组中的数对 K-diff Pairs in an Array](../0532.k-diff-pairs-in-an-array/index.md) + +TODO: + - [29. 两数相除](https://leetcode.com/problems/divide-two-integers) - [33. Search in Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/description/) - [34. 在排序数组中查找元素的第一个和最后一个位置](https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array) diff --git a/src/leetcode/tags/hash-table.md b/src/leetcode/tags/hash-table.md index 944b4609..06dbbe58 100644 --- a/src/leetcode/tags/hash-table.md +++ b/src/leetcode/tags/hash-table.md @@ -23,6 +23,11 @@ ## 中等 +1. [0167. 两数之和 II - 输入有序数组 Two Sum II - Input Array Is Sorted](../0167.two-sum-ii-input-array-is-sorted/index.md) +2. [0532.数组中的数对 K-diff Pairs in an Array](../0532.k-diff-pairs-in-an-array/index.md) + +TODO: + - [3.无重复字符的最长子串](https://leetcode.com/problems/longest-substring-without-repeating-characters) - [215. 数组中的第K个最大元素](https://leetcode.com/problems/kth-largest-element-in-an-array) - [347. 前 K 个高频元素](https://leetcode.com/problems/top-k-frequent-elements) diff --git a/src/leetcode/tags/two-pointers.md b/src/leetcode/tags/two-pointers.md index 84a7da77..aa02fd81 100644 --- a/src/leetcode/tags/two-pointers.md +++ b/src/leetcode/tags/two-pointers.md @@ -24,6 +24,7 @@ TODO: 2. [0015. 三数之和 3Sum](../0015.3sum/index.md) 3. [0080. 删除排序数组中的重复项 II Remove Duplicates from Sorted Array II](../0080.remove-duplicates-from-sorted-array-ii/index.md) 4. [0167. 两数之和 II - 输入有序数组 Two Sum II - Input Array Is Sorted](../0167.two-sum-ii-input-array-is-sorted/index.md) +5. [0532.数组中的数对 K-diff Pairs in an Array](../0532.k-diff-pairs-in-an-array/index.md) TODO: @@ -32,6 +33,5 @@ TODO: 3. [142. 环形链表 II](https://leetcode.com/problems/linked-list-cycle-ii) 4. [443. 压缩字符串](https://leetcode.com/problems/string-compression) 5. [524. 通过删除字母匹配到字典里最长单词](https://leetcode.com/problems/longest-word-in-dictionary-through-deleting) -6. [532.数组中的数对](https://leetcode.com/problems/k-diff-pairs-in-an-array) -7. [986. 区间列表的交集](https://leetcode.com/problems/interval-list-intersections) -8. [1498. 满足条件的子序列数目](https://leetcode.com/problems/number-of-subsequences-that-satisfy-the-given-sum-condition) +6. [986. 区间列表的交集](https://leetcode.com/problems/interval-list-intersections) +7. [1498. 满足条件的子序列数目](https://leetcode.com/problems/number-of-subsequences-that-satisfy-the-given-sum-condition)