class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型vector 
     * @return int整型
     */
    int findRainbow(vector<int>& nums) {
        // write code here
        // 如果是第一次遇到子序列和子数组的概念,可能会搞不清楚两者区别。
        // 原始数组:[1,2,3,4,5]
        // 子序列:从原始数组里选一些元素,元素可以不连续,但一定要保持原始的相对顺序
        // 子序列举例:[],[1,3,5],[2,4],[1,2,5]
        // 子数组:从原始数组里连续选取一整段出来。
        // 子数组举例:[],[1,2,3],[2,3],[1,2,3,4,5]
        // 可以看出来,子数组一定是子序列,反过来不一定对。
        //
        // 这个问题要利用同余定理
        // 简单介绍一下同余定理的应用,如果两个数除以同一个数得到的余数相同,
        // 这两个数相减的结果正好是前面相同除数的倍数。
        // 举例:9 / 7 = 1 ... 2,16 / 7 = 2 ... 2,16 - 9 = 7 = 7 * 1
        //
        // 这道题还是前缀和思想,对每个前缀和取模 7 之后的结果,记录每种结果第一次出现的位置。
        // 如果在某个位置上再次出现相同的模 7 结果,两个位置之间的子数组的和是 7 的倍数。
        // 如果某个前缀和的结果直接模 7 就是 0,那也不用再找了,已经找到了。
        // 如果某个元素本身就是 7 的倍数,那也不用再找了,长度为 1 的子数组(也是子序列)找到了。
        unordered_map<int, int> modMap;
        modMap[0] = -1;
        int prefixSum = 0;

        for (int i = 0; i < nums.size(); ++i) {
            if (nums[i] % 7 == 0) {
                // cout << "nums[i] % 7 == 0" << endl;
                return 1;
            }

            prefixSum += nums[i];
            int mod = prefixSum % 7;
            // cout << "mod = " << mod << endl;
            
            if (modMap.find(mod) != modMap.end()) {
                // cout << "modMap.find(mod) != modMap.end()" << endl;
                return 1;
            }
            modMap[mod] = i;
        }

        // 什么条件都不满足,找不到,直接返回 0
        // 多提一嘴,我这种思路一直在找子数组,而子数组是子序列的特例,判断其实是不完整的
        // 如果要找不连续的子序列,上面的代码就抓瞎了。
        // 举个例子,输入是 [1,2,3,12,5],如果按照题意是能找到 [2,12] 或者 [2,5] 这样的子序列的,
        // 但是上面的代码只能找子数组找不到子序列。
        return 0;
    }
};

上面的代码目前来说可以 AC,但是我感觉这里有点问题。

把打印临时结果都开开,是这样的

上面的代码逻辑找不到 [2,12] 或者 [2,5],这个用例也是我自己编的,没有期望输出这一条。

再看一眼题面,我们没看错啊,题面里要的是子序列。

要不然就修改一下题面,要不然就把我这条用例加进去,现在数据太弱