【问题标题】:Determine if an array of numbers can divided into a set of k consecutive numbers确定一个数字数组是否可以划分为一组 k 个连续数字
【发布时间】:2019-12-22 02:49:42
【问题描述】:

给定一些数组 nums 和一个正整数 k,确定是否可以将此数组划分为 k 个连续数字的集合。

例子:

nums = [1,2,3,4] k = 2

从 [1,2], [3, 4] 开始输出 true

我的想法是数组 nums 的大小必须能被整数 k 整除。但是当我使用它作为测试时,我在这个测试用例中失败了:

[15,16,17,18,19,16,17,18,19,20,6,7,8,9,10,3,4,5,6,20] k = 5

我得到了正确的答案,但答案是错误的,我不知道为什么。有什么想法吗?

这是我的代码:

int n = nums.size();
if(n % k == 0)
    return true;

return false;

如果有帮助,这里还有更多示例:

【问题讨论】:

  • 取数组[2,4,6,8]k = 2。数组的大小可以被k 整除,但没有k 的连续数字序列。
  • @JohnnyMopp 也许我不明白这个问题。如果您的解释和建议的伪代码来解决它,您能否提供答案?
  • 如果您的测试仅取决于数组的长度 - 而根本不取决于数组中的数字 - 那么它不可能是正确的。
  • @sammy 例如,[1,2],[2,3],[3,4] 不是一个有效的解决方案吗?我假设子数组需要与自己连续,而不是其他数组。这个问题需要澄清。
  • 请将您的示例作为文本/代码,而不是图像。

标签: java arrays algorithm


【解决方案1】:

可以通过对数组进行排序,计算重复项,然后验证连续序列来解决问题。

考虑示例 2,其中 k=3 且数组为

[3,2,1,2,3,4,3,4,5,9,10,11]

排序后:

[1,2,2,3,3,3,4,4,5,9,10,11]

计算重复后(最上面一行是数组中唯一的数字,最下面一行是每个数字的重复计数):

1 2 3 4 5 9 10 11
1 2 3 2 1 1  1  1

现在检查序列。最小的数字是1,所以数组中必须存在序列[1,2,3],否则输出为假。 1、2 和 3 都具有非零计数,因此数组 确实 包含该序列。更新计数以删除该序列:

1 2 3 4 5 9 10 11
0 1 2 2 1 1  1  1

现在 2 是非零计数的最小数字,因此下一个序列是 [2,3,4],更新后的计数是:

1 2 3 4 5 9 10 11
0 0 1 1 1 1  1  1

以 [3,4,5] 和 [9,10,11] 结束

【讨论】:

    【解决方案2】:

    解决办法:

    第 1 步。使用 TreeMap 存储数组元素及其出现。 Treemap 帮助我们按排序顺序存储元素。

    第二步。遍历树形图,直到它不为空。

    第三步。从treemap中取出第一个key(firstKey),开始搜索下一个K连续元素。

    public static boolean isPossibleDivide(int[] arr, int k) {
    
        TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
        for (int i = 0; i < arr.length; i++) {
            map.put(arr[i], map.get(arr[i]) != null ? map.get(arr[i]) + 1 : 1);
        }
        while (!map.isEmpty()) {
            int firstKey = map.firstKey();
    
            for (int i = 0; i < k; i++) {
    
                int key = firstKey + i;
    
                if (!map.containsKey(key)) {
                    return false;
                } else {
                    map.put(key, map.get(key) - 1);
    
                    if (map.get(key) == 0)
                        map.remove(key);
                }
            }
        }
        return true;
    }
    

    【讨论】:

    • 我有一个快速的问题- 输入:nums = [1,2,3,4], k = 3 输出:false 解释:每个数组都应该分成大小为 3 的子数组。但是在你的您尚未验证此逻辑的代码。你能解释一下它是如何工作的吗?
    【解决方案3】:
    bool isPossibleDivide(vector<int>& nums, int k) {
        int n = nums.size();
        if(n%k != 0)return false;
        sort(nums.begin(),nums.end());
        map<int,int> m;
        for(int i=0;i<n;i++){
            m[nums[i]]++;
        }
        int nu = m.size() - k + 1;
        for(auto it=m.begin();it!=m.end();it++){
            if(!nu)break;
            int x = it->second;
            int l=0;
            map<int,int> :: iterator s = it;
            map<int,int> :: iterator s1 = s ;
            while(l<k){
                s->second = s->second - x;
                s++;
                if(s->first - s1->first !=1 && l<k-1)return false;
                s1++;
                l++;
            }
            nu--;
        }
        /*for(auto it=m.begin();it!=m.end();it++){
            cout << it->first <<" "<<it->second <<endl;
        }*/
        for(auto it=m.begin();it!=m.end();it++){
            if(it->second != 0) return false;
        }
        return true;
    }
    

    我已经这样做了,但我不知道为什么它不起作用

    【讨论】:

    • 是的,只能回答其中两个问题,不知道有些人如何在不到 20 分钟的时间内解决所有问题
    • 只能解决前两个问题。其他的都很难,第二个问题有点棘手
    猜你喜欢
    • 1970-01-01
    • 2018-03-18
    • 2014-11-16
    • 2019-06-28
    • 2011-02-07
    • 2018-07-28
    • 1970-01-01
    • 2022-10-01
    • 2019-09-19
    相关资源
    最近更新 更多