LeetCode 954. 二倍数对数组

题目描述

954. 二倍数对数组

思路分析

解法一:排序 + 贪心(推荐)

核心思路

  • 将数组按绝对值从小到大排序,保证每次遇到一个数时,其对应的”一半”或”二倍”一定已经或正在被处理
  • 使用哈希表记录每个数字剩余的未配对数量
  • 按排序后的顺序遍历:若当前数字 x 的一半(x/2)存在于哈希表中,则优先与其配对;否则当前数字等待配对,计入哈希表
  • 最终哈希表为空则说明可以完成所有配对


复杂度分析

  • 时间复杂度:O(n log n),其中 n 表示数组长度,主要来自排序
  • 空间复杂度:O(n),哈希表存储最多 n 个元素
class Solution {
    public boolean canReorderDoubled(int[] arr) {
        // 使用哈希表统计每个数字的出现次数
        Map<Integer, Integer> count = new HashMap<>();
        for (int num : arr) {
            count.merge(num, 1, Integer::sum);
        }

        // 按绝对值从小到大排序
        Integer[] keys = count.keySet().toArray(new Integer[0]);
        Arrays.sort(keys, Comparator.comparingInt(Math::abs));

        // 贪心配对
        for (int key : keys) {
            int cnt = count.getOrDefault(key, 0);
            if (cnt == 0) {
                continue;
            }

            // 尝试与 key * 2 配对
            int doubleKey = key * 2;
            if (count.getOrDefault(doubleKey, 0) < cnt) {
                return false;
            }

            count.put(doubleKey, count.get(doubleKey) - cnt);
            count.put(key, 0);
        }

        return true;
    }
}
func canReorderDoubled(arr []int) bool {
    // 使用哈希表统计每个数字的出现次数
    count := make(map[int]int)
    for _, num := range arr {
        count[num]++
    }

    // 收集所有键并按绝对值排序
    keys := make([]int, 0, len(count))
    for k := range count {
        keys = append(keys, k)
    }
    sort.Slice(keys, func(i, j int) bool {
        return abs954(keys[i]) < abs954(keys[j])
    })

    // 贪心配对
    for _, key := range keys {
        cnt := count[key]
        if cnt == 0 {
            continue
        }

        // 尝试与 key * 2 配对
        doubleKey := key * 2
        if count[doubleKey] < cnt {
            return false
        }

        count[doubleKey] -= cnt
        count[key] = 0
    }

    return true
}

func abs954(x int) int {
    if x < 0 {
        return -x
    }
    return x
}

相似题目

题目 难度 考察点
1. 两数之和 简单 哈希表、数组
2007. 从双倍数组中还原原数组 中等 哈希表、排序、贪心
1657. 确定两个字符串是否接近 中等 哈希表、字符串
532. 数组中的 k-diff 数对 中等 哈希表、排序
1010. 总持续时间可被 60 整除的歌曲 中等 哈希表、数组
本文作者:
本文链接: https://hgnulb.github.io/blog/2022/13201592
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!