• 358. K 距离间隔重排字符串 排序


    358. K 距离间隔重排字符串

    给你一个非空的字符串 s 和一个整数 k ,你要将这个字符串 s 中的字母进行重新排列,使得重排后的字符串中相同字母的位置间隔距离 至少 为 k 。如果无法做到,请返回一个空字符串 ""

    示例 1:

    输入: s = "aabbcc", k = 3
    输出: "abcabc" 
    解释: 相同的字母在新的字符串中间隔至少 3 个单位距离。
    

    示例 2:

    输入: s = "aaabc", k = 3
    输出: "" 
    解释: 没有办法找到可能的重排结果。
    

    示例 3:

    输入: s = "aaadbbcc", k = 2
    输出: "abacabcd"
    解释: 相同的字母在新的字符串中间隔至少 2 个单位距离。
    

    提示:

    • 1 <= s.length <= 3 * 10^5
    • s 仅由小写英文字母组成
    • 0 <= k <= s.length

    做题结果

    成功,优先队列,滑动窗口都没用,就纯纯的排序+数组+集合(也可以不要,就纯数组也行)

    方法:排序

    1. 有长度为 n 的字符串,每k 个分为一组,可以分出 part=(n+k-1)组,那如果有字符数目超过part,一定无法构成模板串,直接返回

    2. 字母用数组计数,记录每种字符的数量

    3. 长度大于0的放入列表,按数量倒排

    4. 每次取尽量数量多的 k 的字符,放入答案

    5. 需要检查索引位置,如果和前面距离太近了,那就换同样数量的其他字母试试

    6. 每次排一下顺序(只有长度26,所以一直排也没关系)

    1. class Solution {
    2. public String rearrangeString(String s, int k) {
    3. if(k==0) return s;
    4. int[] arr = new int[26];
    5. int n = s.length();
    6. int part = (n+k-1)/k;//每部分最大几个
    7. for(int i = 0; i < n; i++){
    8. int index = s.charAt(i)-'a';
    9. arr[index]++;
    10. if(arr[index]>part){
    11. return "";
    12. }
    13. }
    14. //按数量顺序倒序
    15. List<int[]> list = new ArrayList<>();
    16. for(int i = 0; i < 26; i++){
    17. if(arr[i]>0){
    18. list.add(new int[]{i,arr[i]});//字母,数量
    19. }
    20. }
    21. //按数量倒排
    22. list.sort((a,b)->b[1]-a[1]);
    23. int[] lastId = new int[26];//上次的索引位
    24. Arrays.fill(lastId,-1);
    25. StringBuilder sb = new StringBuilder();
    26. boolean move = true;
    27. for(int i = 0; i < n&&move; ){
    28. move = false;
    29. //从数量多分配到数量少的
    30. for (int[] data : list) {
    31. //没得分跳出
    32. if (data[1] == 0) break;
    33. int id = sb.length();
    34. //距离不够远,跳过
    35. if(lastId[data[0]]!=-1 && id-lastId[data[0]]<k)
    36. continue;
    37. //本轮进行了操作
    38. move = true;
    39. lastId[data[0]] = id;
    40. sb.append((char) (data[0] + 'a'));
    41. --data[1];
    42. ++i;
    43. //集齐k个本轮结束
    44. if (sb.length()%k==0) {
    45. break;
    46. }
    47. }
    48. //数量变化,重新排
    49. list.sort((a,b)->b[1]-a[1]);
    50. }
    51. return sb.length()==n?sb.toString():"";
    52. }
    53. }

  • 相关阅读:
    C#同步调用sync与异步调用Async
    长短期记忆神经网络(LSTM)的回归预测(免费完整源代码)【MATLAB】
    MongoDB教程(二):mongoDB引用shell
    端口被占用怎么解决
    ssm课堂考勤管理毕业设计-附源码191617
    Oracle转Poatgresql,ora2pg工具安装使用
    iptables之SNAT,DNAT原理与DNS分离解析实验
    10月BIOTREE协助发表文章再创新高,最高影响因子31.373
    软件设计师 程序设计语言
    【数模系列】01_聚类分析
  • 原文地址:https://blog.csdn.net/yu_duan_hun/article/details/125507173