Loading

力扣 - 821. 字符的最短距离

题目

821. 字符的最短距离

思路1

  • 使用一个res数组,而且要初始化为Integer.MAX_VALUE

  • 从左到右遍历字符串,直到遇到我们的目标字符时候停下来

  • 以目标字符为中心,pre和next双指针向两边移动,并且给数组赋值,从1开始递增

  • 如果指针再移动过程中遇到当前的值大于等于左边/右边的值,那么就结束该指针的移动

代码

class Solution {
    public int[] shortestToChar(String S, char C) {
        int len = S.length();
        int[] res = new int[len];
        // 填充最大值
        Arrays.fill(res, Integer.MAX_VALUE);

        for (int i = 0; i < len; i++) {
            //每次遇到e时候,就进行pre和next的移动
            if (S.charAt(i) == C) {
                res[i] = 0;
                int pre = i-1;
                int next = i+1;
                int t = 1;
                // 赋值的条件是t要小于等于前一个/后一个元素的值
                // 进行左移动赋值
                while (pre >= 0 && t < res[pre]) {
                    res[pre--] = t++;
                }
                t = 1;
                // 进行右移动赋值
                while (next < len && t < res[next]) {
                    res[next++] = t++;
                }
            }
        }
        // 得到结果
        return res;
    }
}

复杂度分析

  • 时间复杂度:\(O(N^2)\),其中 N 为字符串长度。
  • 空间复杂度:\(O(N)\),其中 N 为res数组长度

思路2

  • 正向遍历一次,反向遍历一次
  • pre标记出现目标字符的位置,利用i的自增,同时给数组赋值
  • 正向遍历是给目标字符之后到下一个目标字符之前进行赋值,反向遍历则相反

代码

class Solution {
    public int[] shortestToChar(String s, char c) {
        int len = s.length();
        int[] res = new int[len];
        // 必须要除以2,因为Integer.MIN_VALUE已经是最小值了,又因为i>=0,所以 i-pre 会超过整型最大值
        int pre = Integer.MIN_VALUE / 2;
        
        // 正向遍历
        for (int i = 0; i < len; i++) {
            if (s.charAt(i) == c) {
                pre = i;
            }
            res[i] = i - pre;
        }

        // 反向遍历
        pre = Integer.MAX_VALUE;
        for (int i = len - 1; i >= 0; i--) {
            if (s.charAt(i) == c) {
                pre = i;
            }
            res[i] = Math.min(res[i], pre - i);
        }

        return res;
    }
}

复杂度分析

  • 时间复杂度:\(O(N)\),其中 N 为字符串长度。
  • 空间复杂度:\(O(N)\),其中 N 为res数组长度
posted @ 2020-11-02 00:55  linzeliang  阅读(101)  评论(0)    收藏  举报