leecode每日一题 1054 距离相等的条形码

对于给定的一排条形码,需要重新排列以确保相邻条形码不相等。题解提出了一种避免使用大根堆的策略,通过插空法实现。首先统计需要插入不同条形码的位置,然后从数组尾部选择元素,按条件插入正确位置,直至所有空位填满。当尾部元素与前一个元素相同或能填补现有空位时,空位计数减少。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

在一个仓库里,有一排条形码,其中第 i 个条形码为 barcodes[i]。请你重新排列这些条形码,使其中任意两个相邻的条形码不能相等。 你可以返回任何满足该要求的答案,此题保证存在答案。

示例 1:

输入:barcodes = [1,1,1,2,2,2]
输出:[2,1,2,1,2,1]

示例 2:

输入:barcodes = [1,1,1,1,2,2,3,3]
输出:[1,3,1,3,2,1,2,1]

题解

官网题解是让用大根堆,但是我觉得有点过于复杂。

我得思路是利用插空法,只要我做一个遍历,能让数组里面没有需要插空的位置,那么这个就算弄好了。

1. 先统计这个数组里面,需要插空的空位。当两个位置连续的元素值一样,那么就认为需要插入和这两个元素不同德元素,才能保证相同数字不连续。

2.我就以这个数值作为判断的依据,当这个空位值为0,我就认为数组中已经不存在相同且连续的数字。

3. 每次我都会从数组尾部拿出一个元素,把他放到该放的位置,直到空位置为0。

4. 什么情况下,这个空位置会被减少呢,有且只有两种情况:

  • 数组尾部的的元素,和它前一个元素相同,那么他们之间有一个空位要填,如果把尾部的元素拿走,填到其他地方,就破坏了这个空位,那么就可以减少一个空位。
  • 数组尾部的的元素,放到一个与它相邻元素的值都不一样的位置,如果这两个相邻元素是一样的,那么相当于这个尾部元素就把一个空位给填了,那么就可以减少一个空位。
class Solution {
    public int[] rearrangeBarcodes(int[] barcodes) {
        int length = barcodes.length;
        if (length <= 2) {
            return barcodes;
        }

        int locations = 0;
        for (int i = 0; i < barcodes.length - 1; i++) { //1.统计空位
            if (barcodes[i] == barcodes[i + 1]) {
                locations++;
            }
        }

        while (locations > 0) { //2.以这个空位作为判断,当空位都填满(即为0),就说明数组处理好了。
            int tail = barcodes[length - 1]; //3. 每次都会从数组尾部拿出一个元素,把他放到该放的位置。
            int l = 0;
            while (l < length) {
                if ((l == 0 && barcodes[l] != tail)
                        || barcodes[l] != tail && barcodes[l - 1] != tail) {
                    if (barcodes[length - 2] == tail) { //4.1 尾部元素和它前一个元素相同,移走尾部元素,也就破环了一个空位,所以可以减1
                        locations--; 
                    }

                    if (l != 0 &&  barcodes[l] == barcodes[l - 1]){ //4.2 放入的位置,相邻元素相同,说明填充了一个空位,所以也可以减1
                        locations--;
                    }

                    System.arraycopy(barcodes, l, barcodes, l + 1, length - l - 1);
                    barcodes[l] = tail;
                    break;
                } else {
                    l++;
                }
            }
        }

        return barcodes;

    }
}

提交结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值