leetcode 821. 字符的最短距离

题目链接
思路一:双指针
分析:
如果里面只有一个和c相同的字符。那么很好处理,只要计算和这个字符的距离即可。
如果里面有两个或两个以上。
将第一个的下标记为p1,第二个的下标记为p2。
当i<=p1的时候,最近的距离肯定是p1-i。
当i>p1 && i<= (p1+p2)/2,最近的距离是res[i] = i-p1;
当i>(p1+p2)/2,最近的距离是res[i]=p2-i;
此时要更新两个指针。
p2=p1
p2更新为下一个与c相同的字符。
代码:

class Solution {
    public int[] shortestToChar(String s, char c) {
        int[] res = new int[s.length()];
        int p1=0;
        while(s.charAt(p1)!=c){
            p1++;
        }
        int p2 = p1+1;
        while(p2<s.length() && s.charAt(p2)!=c){
            p2++;
        }
        for(int i=0; i<s.length(); i++){
            if(p2==s.length()){
                if(i<=p1){
                    res[i] = p1-i;
                }else{
                    res[i] = i-p1;
                }
                continue;
            }
            if(i<=p1){
                res[i]=p1-i;
            }else if(i>p1 && i<= (p1+p2)/2){
                res[i] = i-p1;
            }else if(i>(p1+p2)/2){
                res[i]=p2-i;
                p1=p2;
                p2++;
                while(p2<s.length() && s.charAt(p2)!=c){
                    p2++;
                }
            }
        }
        return res;
    }
}

思路二:两次遍历
分析:这个问题可以拆分为对于每个字符,求:

  • 左边最近的字符c的距离
  • 右边最近的字符c的距离
    这两者的最小值。

对于问题一,可以从左往右遍历s,若当前字符等于c,那么更新idx为当前下标。遍历的同时更新res[i]=i-idx;
对于问题二,可以从右往左遍历,若当前字符等于c,那么更新idx为当前下标。
遍历的同时更新res[i]=Math.min(res[i,idx-i).
因为最开始idx是不存在的,所以可以用-n或2n来表示。
代码:

class Solution {
    public int[] shortestToChar(String s, char c) {
        int n = s.length();
        int[] ans = new int[n];

        for (int i = 0, idx = -n; i < n; ++i) {
            if (s.charAt(i) == c) {
                idx = i;
            }
            ans[i] = i - idx;
        }

        for (int i = n - 1, idx = 2 * n; i >= 0; --i) {
            if (s.charAt(i) == c) {
                idx = i;
            }
            ans[i] = Math.min(ans[i], idx - i);
        }
        return ans;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值