LeetCode每日一题(767. Reorganize String)

Given a string s, rearrange the characters of s so that any two adjacent characters are not the same.

Return any possible rearrangement of s or return “” if not possible.

Example 1:

Input: s = “aab”
Output: “aba”

Example 2:

Input: s = “aaab”
Output: “”

Constraints:

  • 1 <= s.length <= 500
  • s consists of lowercase English letters.

这题一开始用 DP 的方法解, 怎么解怎么超时, 后来没办法看提示, Alternate placing the most common letters., 想想, 貌似是这个道理。改变策略最终解决。具体方法是把字符串中每个字母的出现频次放到一个 BinaryHeap 中, 每次 pop 一下, 取出一个字母, 把该字母 push 到要返回的字符串中, 然后再把频次-1,然后再把该字母和频次放回 Heap 中, 过程中记得检查 pop 出的字母是不是与返回字符串的最后一个字母相同, 如果相同则继续对 heap 进行 pop 操作, 还有在放回字母和频次之前先检查一下频次是不是大于 0, 如果等于 0 那就不需要放回了。


use std::collections::BinaryHeap;

impl Solution {
    pub fn reorganize_string(s: String) -> String {
        let mut counts: BinaryHeap<(i32, char)> = s
            .chars()
            .fold(vec![0; 26], |mut l, c| {
                l[c as usize - 97] += 1;
                l
            })
            .into_iter()
            .enumerate()
            .map(|(i, v)| (v, (i as u8 + 97) as char))
            .filter(|(v, _)| v > &0)
            .collect();
        let mut ans = String::new();
        while !counts.is_empty() {
            let mut stack = Vec::new();
            let mut ok = false;
            while let Some((count, c)) = counts.pop() {
                if let Some(last) = ans.chars().last() {
                    if c == last {
                        stack.push((count, c));
                        continue;
                    }
                }
                ok = true;
                ans.push(c);
                stack.push((count - 1, c));
                break;
            }
            if !ok {
                return "".into();
            }
            for (count, c) in stack {
                if count > 0 {
                    counts.push((count, c));
                }
            }
        }
        ans
    }
}

你可能感兴趣的:(算法,数据结构,leetcode,算法)