767. 重构字符串

题目 https://leetcode.cn/problems/reorganize-string/
答案 https://www.youtube.com/watch?v=2cUKLq-OAoA

从5:00开始,讲到greedy解法。
从高频次向低频次放置字母,先将字母都放置到奇数位置,如果没空间了,再都放置到偶数位置,这样相同的字符一定不会相邻。。

但是,要首先判断是否有字母出现次数超过一半(向上取整),如果是,则不可能摆成功。

因为,如果字符串长度是偶数,那至多有两种字母各出现一半次数。如果长度是奇数,那至多有一种字母出现n/2 + 1次。所以,只要字母不超过一半,一定能有办法摆放它。

class Solution {
    public static class Item {
        int ch;
        int value;

        public Item(int ch, int value) {
            this.ch = ch;
            this.value = value;
        }
    }

    public String reorganizeString(String s) {
        int[] count = new int[26];
        for (char c : s.toCharArray()) {
            count[c - 'a']++;
        }

        int limit = (s.length() + 1) / 2;

        for (int c : count) {
            if (c > limit) {
                return "";
            }
        }

        PriorityQueue<Item> q = new PriorityQueue<>((o1, o2) -> o2.value - o1.value);
        for (int i = 0; i < 26; i++) {
            q.add(new Item(i, count[i]));
        }

        char[] arr = new char[s.length()];
        int idx = 0;
        Item cur = q.poll();
        for (int i = 0; i < s.length(); i++) {
            arr[idx] = (char)(cur.ch + (int)'a');
            cur.value--;
            if (cur.value == 0) {
                cur = q.poll();
            }

            idx += 2;
            if (idx >= s.length()) {
                idx = 1;
            }
        }
        return new String(arr);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值