首页 > 其他分享 >【优先队列】【堆排序实现优先队列】[1054. 距离相等的条形码](https://leetcode.cn/problems/distant-barcodes/)

【优先队列】【堆排序实现优先队列】[1054. 距离相等的条形码](https://leetcode.cn/problems/distant-barcodes/)

时间:2023-07-23 11:56:28浏览次数:50  
标签:优先 1054 队列 int heap var new hash barcodes

【优先队列】【堆排序实现优先队列】1054. 距离相等的条形码

在一个仓库里,有一排条形码,其中第 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 <= barcodes.length <= 10000
  • 1 <= barcodes[i] <= 10000
我的解法一
  • dfs暴力枚举

  • 毫无疑问TLO了。。

class Solution {
    List<Integer> ans;
    List<Integer> path = new ArrayList<>();
    boolean[] visit;
    int[] barcodes;

    public void dfs() {
        if(path.size() >= barcodes.length) {
            ans = new ArrayList(path);
            return ;
        }
        for(var i = 0; i < barcodes.length; i++) {
            if ((path.size() == 0) || (!visit[i] && barcodes[i] != path.get(path.size()-1))) {
                path.add(barcodes[i]);
                visit[i] = true;
                dfs();
                path.remove(path.size()-1);
                visit[i] = false;
            }
        }
    }

    public int[] rearrangeBarcodes(int[] barcodes) {
        this.barcodes = barcodes;
        this.visit = new boolean[barcodes.length];
        dfs();
        return ans.stream().mapToInt(Integer::valueOf).toArray();
    }
}
我的解法二
  • 维护一个hash数组,每次都去遍历一遍获取最大值和次大值加入结果数组
  • 也TLO了。。
class Solution {

    public int[] rearrangeBarcodes(int[] barcodes) {
        var ans = new ArrayList<Integer>();
        var hash = new int[10000+1];
        for(var i = 0; i < barcodes.length; i++) {
            hash[barcodes[i]]++;
        }
        while(ans.size() < barcodes.length) {
            var maxPos = 0;
            var maxCount = 0;
            for(var i = 0; i <= 10000; i++) {
                if(hash[i] > maxCount) {
                    maxCount = hash[i];
                    maxPos = i;
                }
            }
            ans.add(maxPos);
            hash[maxPos]--;

            if(ans.size() >= barcodes.length) {
                break;
            }

            var next = maxPos;
            while(hash[next] <= 0 || next == maxPos) {
                next = (next + 1) % 10000; 
            }

            hash[next]--;
            ans.add(next);
        }

        return ans.stream().mapToInt(Integer::valueOf).toArray();
    }
}
优先队列
  • 和上面的思想大同小异,获取最大值和次大值加入结果数组
  • 以前没接触过优先级队列,会自动对加入数据进行定义排序
class Solution {

    public int[] rearrangeBarcodes(int[] barcodes) {
        var hash = new int[10000+1];
        for (int barcode : barcodes) {
            hash[barcode]++;
        }
        var q = new PriorityQueue<int[]>((a, b) -> {
            if(b[1] != a[1]) {
                return b[1] - a[1];
            }
            return a[0] - b[0];
        });

        for(var i = 0; i <= 10000; i++) {
            if(hash[i] > 0) {
                q.add(new int[]{i, hash[i]});
            }
        }

        var index = 0;
        while(!q.isEmpty()) {
            var first = q.remove();
            first[1]--;
            barcodes[index++] = first[0];

            if(!q.isEmpty()) {
                var second = q.remove();
                second[1]--;
                barcodes[index++] = second[0];
                if(second[1] > 0) {
                    q.add(second);
                }
            }
            
            if(first[1] > 0) {
                q.add(first);
            }
        }

        return barcodes;
    }
}
堆排序
  • 一说到动态获取最大、最小值,那么堆排序肯定是少不了的
  • 因为是获取最大值,所以使用大顶堆
  • 如果最大值和前面的重复,则选择第二大的:选择第二大的方法就是将堆的最后一个元素和第一个元素替换然后计算 n - 2 的自底向上即可
class Solution {
    int[][] heap;
    // 大顶堆自下而上
    public void downToUp(int n) {
        for(var i = n/2; i >= 0; i--) {
            if(heap[i * 2][1] > heap[i][1]) {
                var dumy = heap[i * 2];
                heap[i * 2] = heap[i];
                heap[i] = dumy;
            } else if(i * 2 + 1 <= n 
                && heap[i * 2 + 1][1] > heap[i][1]) {
                var dumy = heap[i * 2 + 1];
                heap[i * 2 + 1] = heap[i];
                heap[i] = dumy;
            }
        }
    }

    public int[] rearrangeBarcodes(int[] barcodes) {
        var len = barcodes.length;
        var hash = new int[10000+1];

        var map = new HashMap<Integer, Integer>();
        for(var i = 0; i < len; i++) {
            map.put(barcodes[i], map.getOrDefault(barcodes[i], 0) + 1);
        }
        var count = 0;
        this.heap = new int[map.size()][2];
        for(var item : map.entrySet()) {
            heap[count++] = new int[]{item.getKey(), item.getValue()};
        }
        var index = 0;
        while(index < len) {
            // 找出最大
            downToUp(count-1);
            if(index == 0 || barcodes[index-1] != heap[0][0]) {
                barcodes[index++] = heap[0][0];
                heap[0][1]--;
            } else {
                // 找出第二大
                var dumy = heap[0];
                heap[0] = heap[count-1];
                heap[count-1] = dumy;
                downToUp(count-2);
                barcodes[index++] = heap[0][0];
                heap[0][1]--;
            }
            
        }
        return barcodes;
    }
}

标签:优先,1054,队列,int,heap,var,new,hash,barcodes
From: https://www.cnblogs.com/tod4/p/17574828.html

相关文章

  • day10 栈与队列
    232.用栈实现队列题解:这一题在大学的时候学过,用两个栈来实现队列,队列是先进先出,而栈是先进后出,所以需要两个栈一个用来存队列入队的数据,出队列的时候,需要将顺序调转,这时候就需要用到另一个队列,注意好边界条件就行225.用队列实现栈题解:队列实现栈的功能也不难,主要是想到栈......
  • python 实现队列
    Python实现队列引言在计算机科学中,队列是一种常见的数据结构,用于存储和管理元素。队列采用先进先出(FIFO)的原则,即最先进入队列的元素最先被处理。在Python中,可以使用列表和相关的操作来实现队列。本文将介绍如何使用Python实现队列,并提供详细的代码示例和解释。实现步骤下表展......
  • 黑魂 211深度优先搜索方法制作双手控制
    创建一个新脚本TransformHelpers放进Scripts文件夹的Helper文件夹里接下来要实现往Unity放进新的定义方法。把TransformHelpers修改成: 把这个hihi方法放进WeaponManager的start函数里: 测试这个方法在运行的时候调用的过程。接下来我们按照hihi方法的参数重新创建一个方法......
  • 一个故事告诉你什么是消息队列
    有一天,产品跑来说:“我们要做一个用户注册功能,需要在用户注册成功后给用户发一封成功邮件。”小明(攻城狮):“好,需求很明确了。”不就提供一个注册接口,保存用户信息,同时发起邮件调用,待邮件发送成功后,返回用户操作成功。没一会功夫,代码就写完了。验证功能没问题后,就发布上线了。线上......
  • 深度优先搜索dfp学习
    >>定义深度优先搜索属于图算法的一种,英文缩写为DFS即DepthFirstSearch.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次.(accordingtoBaidu)>>几个例子eg11215迷宫 (求是否有路径)http://ybt.ssoier.cn:8088/problem_show.php?pi......
  • php与 redis的队列 && 如何守护进程?
    在PHP中,使用队列可以解决以下情况下的一些常见问题:异步任务处理:当应用程序需要处理一些耗时的任务,如发送电子邮件、生成报表、处理文件上传等,可以将这些任务添加到队列中,并使用队列进行异步处理,从而不影响主要的用户请求处理。消息通信:在分布式系统或微服务......
  • leetcode 栈与队列 232 225
    目录基本介绍四个问题232225基本介绍栈,先进后出队列,先进先出四个问题C++中stack是容器么?我们使用的stack是属于哪个版本的STL?我们使用的STL中stack是如何实现的?stack提供迭代器来遍历stack空间么?首先大家要知道栈和队列是STL(C++标准库)里面的两个数据结构。C++标准......
  • 深入理解队列
    理解队列:从生活中的排队到计算机的数据结构队列(Queue)是计算机科学中一种常见的数据结构,它在计算机程序和算法中扮演着重要角色。然而,队列的概念并不仅仅局限于计算机领域,我们在日常生活中也能够轻松地找到许多队列的例子。本文将介绍队列的基本概念、实现方式以及它在计算机科学......
  • 队列的具体实现方式
    队列可以通过两种常见的实现方式来表示:顺序队列(数组实现)和链式队列(链表实现)。这两种方式在计算机科学中都广泛使用,每种实现方式都有其优势和适用场景。1.顺序队列(数组实现):顺序队列是使用数组来表示队列的一种实现方式。在顺序队列中,我们使用一个固定大小的数组来存储队列的元素......
  • 伪类选择器,伪元素选择器,选择器的优先级,CSS属性相关
    伪类选择器<style>/*未访问时候显示的*/a:link{color:#FF0000;}/*鼠标移动到链接上*/a:hover{color:#FF00FF}/*选定的链接*/a:active{color:#0000......