leetcode
leetcode 201 ~ 250
中心对称数 III

中心对称数 III

难度:

标签:

题目描述

代码结果

运行时间: 34 ms, 内存: 16.3 MB


/*
 * 思路:
 * 1. 使用 Java Stream API 和一个 HashMap 来实现。
 * 2. Stream 中的 forEach 代替传统的 for 循环。
 * 3. 使用一个原子引用来存储结果。
 */
 
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.IntStream;
 
public class TwoSumStream {
    public int[] twoSum(int[] nums, int target) {
        HashMap<Integer, Integer> map = new HashMap<>();
        AtomicReference<int[]> result = new AtomicReference<>(new int[0]);
        IntStream.range(0, nums.length).forEach(i -> {
            int complement = target - nums[i];
            if (map.containsKey(complement)) {
                result.set(new int[] { map.get(complement), i });
            }
            map.put(nums[i], i);
        });
        return result.get();
    }
}

解释

方法:

本题使用DFS+记忆化搜索的方法来统计在给定范围内的中心对称数的个数。主要思路是:从高位到低位依次构造中心对称数,在构造的过程中,根据已经构造的前缀判断剩余部分是否能够构成中心对称数,如果可以直接计算出个数,避免重复搜索。同时使用记忆化存储已经搜索过的状态,降低时间复杂度。

时间复杂度:

O(n * 5^(n/2))

空间复杂度:

O(n * 5^(n/2))

代码细节讲解

🦆
为什么在DFS的设计中,使用了`digits = [0,1,6,8,9]`而没有包括其他数字如2,3,4等?
在中心对称数的定义中,数字必须在旋转180度后仍能表示同一个数或有效的对应数。数字2,3,4,5和7旋转后无法得到有效的数字,因此不包含在中心对称数中。有效的中心对称数数字只包括0, 1, 6, 8, 9,其中6和9旋转后互为对方,0、1、8旋转后保持不变。
🦆
在函数`flip`中,如果传入的数字字符串中有不是`0,1,6,8,9`的字符,函数会如何处理?是否有错误处理机制?
在提供的`flip`函数中,如果输入的数字字符串包含非`0,1,6,8,9`的字符,将会引发一个KeyError,因为这些字符没有在翻转映射`match`字典中定义。当前的实现没有错误处理机制来处理这种情况,所以在使用`flip`函数之前,需要确保所有字符都是有效的中心对称数字符。
🦆
在递归函数`dfs`中,`limit`参数的具体作用是什么?如何通过这个参数控制搜索范围?
`limit`参数在递归函数`dfs`中用来标识当前的数字构造是否受到原始数字的位限制。如果`limit`为`True`,则当前位置的数字不能超过原始数字对应位置的数字;如果为`False`,则可以自由选择`0,1,6,8,9`中的任一数字。这个参数确保在构造数字时,只有当完全符合原始上界数字的前缀时,才会继续严格匹配上界;否则可以较为自由地构造数字。
🦆
在记忆化搜索时,为什么选择对`dfs`函数使用`@cache`装饰器,而不是手动管理一个记忆化数组?
使用`@cache`装饰器可以自动处理记忆化的细节,如存储已经计算的结果和在后续调用中直接返回这些结果,从而减少代码复杂性和出错的可能性。相比于手动管理记忆化数组,`@cache`提供了一种更简洁和易于维护的方式来实现记忆化,特别是在涉及多个参数的递归函数中这一点尤为重要。它自动地为每个不同的参数组合创建一个缓存条目,避免了复杂的索引和数据结构管理。

相关问题

中心对称数

中心对称数

中心对称数 II

中心对称数 II