• 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. }

  • 相关阅读:
    微信小程序 | 人脸识别的最终解决方案
    抖音小店无货源怎么操作?针对新手小白最新玩法分享,记得收藏
    基于log4cpp封装日志类
    商品大类C
    C++ Reference: Standard C++ Library reference: C Library: cwchar: wmemchr
    浅谈人工智能怎么提升工作效率
    nodejs+vue菜谱美食食谱网站系统
    【AD】【pcb】【布线经验】打孔的目的
    单节点伪分布式Hadoop部署笔记
    Linux命令教程:使用cat命令查看和处理文件
  • 原文地址:https://blog.csdn.net/yu_duan_hun/article/details/125507173