LeetCode767 重构字符串

LeetCode 767

题目描述

给定一个字符串 s ,检查是否能重新排布其中的字母,使得两相邻的字符不同。
返回 s 的任意可能的重新排列。若不可行,返回空字符串 “” 。

示例 :

示例 1:
输入: s = “aab”
输出: “aba”
示例 2:
输入: s = “aaab”
输出: “”

思路

抽屉原理

  • c > n/2上取整,一定无解;
  • c <= n/2上取整,一定有解
    -当n为奇数,当c > n/2上取整 ,先放偶数位置;
    -当c <= n/2, 先放奇数,放满后再放偶数;

代码

class Solution {
    //抽屉原理:c > n/2上取整,一定无解
    // c <= n/2上取整,一定有解
    //情况一:当n为奇数,当c > n/2上取整 ,先放偶数位置;
    //情况二:当c <= n/2, 先放奇数,放满后再放偶数
    public String reorganizeString(String s) {
        int maxc = 0;
        HashMap<Character, Integer> cntMap = new HashMap<>();
        for (var c : s.toCharArray()) {
            cntMap.put(c, cntMap.getOrDefault(c, 0) + 1);
            maxc = Math.max(maxc, cntMap.getOrDefault(c, 0));
        }
        int n = s.length();
        if (maxc > (n + 1) / 2) {
            return "";
        }
        char[] res = new char[n];
        int i = 1, j = 0;
        for (char c = 'a'; c <= 'z'; c ++ ) {
            if (cntMap.getOrDefault(c, 0) <= n / 2) {
                while (cntMap.getOrDefault(c, 0) > 0 && i < n) {
                    res[i] = c;
                    cntMap.put(c, cntMap.getOrDefault(c, 0) - 1);
                    i += 2;
                }
            }
            while (cntMap.getOrDefault(c, 0) > 0 && j < n) {
                res[j] = c;
                cntMap.put(c, cntMap.getOrDefault(c, 0) - 1);
                j += 2;
            }
        }
        return new String(res);
    }
}在这里插入代码片

时间复杂度分析

时间 O(N)空间O(N)

总结

数学思维

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值