You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何重排数组避免连续重复元素?元素过多时拆分至其他数组

解决数组重排无连续重复元素并拆分剩余元素的问题

我来帮你搞定这个数组重排的问题!你需要的是把包含重复元素的数组,重排成无连续重复元素的数组,而且不能删除任何元素;如果某个元素重复次数太多,实在没法全部塞进一个无连续重复的数组里,就把剩下的元素放到单独的rest数组里,对吧?

先说说你之前尝试的那段代码问题在哪:那段递归函数是通过splice直接删除连续重复的元素,这完全不符合你的需求——我们要的是保留所有元素,只是调整位置或者拆分,不是删掉它们。

最优解决思路

核心思路是贪心策略+计数统计,步骤大概是这样:

  • 第一步:先统计每个元素的出现次数,知道哪个元素重复得最多,这是判断能不能全部放进一个数组的关键。
  • 第二步:用贪心的方式构建merged数组——每次优先选择当前剩余次数最多、且和merged最后一个元素不同的元素放进去,这样能最大化利用数组空间,尽量避免出现连续重复。
  • 第三步:当没有符合条件的元素可以放进merged时,剩下的元素全部丢进rest数组。

具体代码实现(JavaScript)

function rearrangeArray(arr) {
    // 1. 统计每个元素的出现次数
    const countMap = new Map();
    arr.forEach(num => {
        countMap.set(num, (countMap.get(num) || 0) + 1);
    });

    const merged = [];
    const rest = [];
    const tempCount = new Map(countMap);
    let lastAddedNum = null;

    // 2. 贪心构建merged数组
    while (merged.length < arr.length) {
        let selectedNum = null;
        let maxRemainingCount = 0;

        // 找到当前剩余次数最多、且不等于上一个添加元素的项
        for (const [num, count] of tempCount) {
            if (count > maxRemainingCount && num !== lastAddedNum) {
                maxRemainingCount = count;
                selectedNum = num;
            }
        }

        // 如果找不到符合条件的元素,说明剩下的都和lastAddedNum重复,直接丢去rest
        if (!selectedNum) {
            for (const [num, count] of tempCount) {
                rest.push(...Array(count).fill(num));
                tempCount.delete(num);
            }
            break;
        }

        // 添加到merged,更新计数
        merged.push(selectedNum);
        const newCount = tempCount.get(selectedNum) - 1;
        if (newCount === 0) {
            tempCount.delete(selectedNum);
        } else {
            tempCount.set(selectedNum, newCount);
        }
        lastAddedNum = selectedNum;
    }

    // 3. 把最后剩下的元素(如果有的话)丢进rest
    for (const [num, count] of tempCount) {
        rest.push(...Array(count).fill(num));
    }

    return { merged, rest };
}

// 测试你的示例
console.log(rearrangeArray([1,2,2,2,3,4,5]));
// 输出示例:{ merged: [2,1,2,3,2,4,5], rest: [] }(顺序可能略有不同,但无连续重复)
console.log(rearrangeArray([1,2,2,2,2,2,2,3,4]));
// 输出示例:{ merged: [2,1,2,3,2,4,2], rest: [2,2] }

思路解释

  • 统计次数是基础,我们需要知道每个元素还有多少个可以用;
  • 贪心选择的逻辑能保证我们尽可能把多的元素先安排好,避免最后出现大量重复元素没法放置的情况;
  • 当找不到能放进merged的元素时,说明剩下的元素都和最后一个添加的元素重复,只能放到rest里,这时候就停止构建merged了。

这个方法能完美满足你的需求:既不删除任何元素,又能尽可能生成无连续重复的数组,实在排不开的元素也会被拆分到rest里。

内容的提问来源于stack exchange,提问作者Yoandry Collazo

火山引擎 最新活动