Java解决删除字符(独家解析)

1、题目描述

      给定一个字符串str,现在要对该字符串进行删除操作,保留字符串中的k个字符且相对位置不变,并且使它的字典序最小,返回这个子串。
      例一

输入:str=“fskacsbi”,k=2
输出:“ab”
解释:“ab“是str中长度为2并且字典序最小的子串

      例二

输入:str=“fsakbacsi”,k=3
输出:“aac”

2、代码

      首先我要说明,我的思路是参考了LintCode用户marshall给出的解决方案,题目链接。我自己也思考了很久这道题的解法,当做记录。

public class Solution {
    /**
     * @param str: the string
     * @param k: the length
     * @return: the substring with  the smallest lexicographic order
     */
    public String deleteChar(String str, int k) {
        //目的是让子串的字典序最小
        int n = str.length();
        char[] result = new char[k];
        char[] list = str.toCharArray();
        for(int i = n-k;i < n;i++){
             result[i-(n-k)] = list[i];
        } 
        for(int i = n-k-1;i >=0 ;i--){
            for(int j = 0;j < k;j++){
                //注意list和result的字符交换的同时字符见的相对位置也发生了变化
                if(list[i] < result[j]){
                    char temp = result[j];
                    result[j] = list[i];
                    list[i] = temp;
                }else if(list[i] > result[j]){
                    break;
                }
            }
        }
        return String.valueOf(result);
    }
}

3、自己的想法

      我看网上好像没有解析呀~当前阶段果然还是菜菜子hhh。首先这道题要明白什么是字典序,字典序的原意是表示英文单词在字典中的先后顺序,在计算机领域中扩展成两个任意字符串的大小关系。对于两个任意的字符串,其大小关系取决于两个字符串从左到右第一个不同字符的 ASCII 值的大小关系。
      我们知道,每一个char对应着一个int,所以我先通过toCharArray()的方法把String转换为字符char。注意,题目要求的是字符串中的k个字符且相对位置不变,并且使它的字典序最小。第二个要关注的重点是,相对位置不变。看到这个问题,我第一个想法是嵌套k个for循环,这当然不可能pass。所以初始化的时候要分成两个数组,一个就是由String转为char的数组list;另一个是result,取自原数组list的倒数k个数。这样做的好处是,保证我们的结果数组result是按照原字符串str中的字符是从左到右按照顺序排列的。
      接下来是外层的for循环,是从list的右往左进行遍历的,举个例子:现有字符(我直接用数字表示大小)按照以下顺序排列 4,1,7,8,n = 4,k = 2:
       1. 7,1,4,8
       2. 8,1,4,7
       3. 8,4,1,7
       4. 8,7,1,4
      最后得到结果1,4,显然按照4,1,7,8的顺序该字符串不存在,正确结果应该为1,7。原因就在于,因为从list从右往左,是不断把位置在右边的更小的字符往result数组右边扔(结合下面的break)。而list左往右,是不断把位置在左边的更小的字符往右边扔,显然会导致顺序颠倒的问题。
       1. 4,7,1,8
       2. 4,8,1,7
       3. 4,8,1,7
      接下来就要说上面正确解法的第三步,为什么list[i] > result[j]之后要break。同理,也是为了防止result中字符顺序颠倒。要保证result[i]的一定在result[i+1]的左边,如果不break,就会出现某个list[m]存在result[i]<list[m]<result[i+1],而list[m]字符的顺序在result[i]的左边。

      PS:有错误希望能指正,觉得不错请给个赞吧,谢谢~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TerryBlog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值