类似于 two points 的解法,非常好的指导思想。

和 821 Shortest Distance to a Character的解题思路是一样的。

题目可以转换成 数组中某个点 到特定字母的最小距离

比如 loveleetcode 求到字母e的最小距离

难点: 字母有可能出现在当前index 的左边或者右边, 或者 两边同时存在,你该怎么搞?

解法: 先left --> right 走一遍,求出距离 再 right --> left 走一遍 求出距离
再比较 二者哪个较小。

有个小tricky, 比如 起始的index 怎么算,对于l 来说 , 第一个leftIndex 算成 多少? 算成一个较小的value 就好了, 比如 - len 这样, 0 -(-len)= len 因为 distance <= len -1 就可以判断这是个无效的距离了。

从right to left, 起始不能用len 表示 , 得至少用 len-1 + len。所以索性用 2len

class Solution {
    public int[] shortestToChar(String S, char C) {
        
       int N = S.length();
        int[] ans = new int[N];
        int prev = Integer.MIN_VALUE/2 ;

        for (int i = 0; i < N; ++i) {
            if (S.charAt(i) == C) prev = i;
            ans[i] = i - prev;
        }

        prev = Integer.MAX_VALUE/2 ;
        for (int i = N-1; i >= 0; --i) {
            if (S.charAt(i) == C) prev = i;
            ans[i] = Math.min(ans[i], prev - i);
        }

        return ans;
    }
}

 



838 题:

多米诺骨牌,类似于821,

1. R . L 看一个点到底是往left 倒 还是 right 倒, 看 点到 R 的距离 和 L 的距离,距离近就向哪边倒。
2. L . R 不会受影响
3. RL . L 这种情况, 如果一个R 已经 遇到L 那得重置。例如 R =0 L =1 .=3 L = 8, . 到R 的距离为3, 但因为 有个L=1 所以 距离 就得是 3- MIN了 。还得往 L 倒。


这题 解法都是 从left to right scan 一遍 记录 . 到 最近的R 的distance, 再从 right to left scan 一遍 . 到 L 的distance, 再scan 一遍 哪个更近。哪个更近就往哪边倒。

    public String pushDominoes(String dominoes) {
        
        int len = dominoes.length();
        int[] leftDis = new int[len];
        int[] rightDis = new int[len];
        final int MAX = len * 2;
        final int MIN = len * -2;
        
        int ri = MIN;
        for(int i=0; i<len; i++){
            if(dominoes.charAt(i) == 'R') ri = i;
            else if(dominoes.charAt(i) == 'L') ri = MIN;
            rightDis[i] = i-ri;
        }
        
        int li = MAX;
        for(int i=len-1; i>=0; i--){
            if(dominoes.charAt(i) == 'L') li=i;
            else if(dominoes.charAt(i) == 'R') li = MAX;
            leftDis[i] = li -i;
        }
        
        char[] ans = new char[len];
        
        for(int i=0; i<len; i++){
            //System.out.println(rightDis[i] + " " + leftDis[i]);
            if(rightDis[i] < leftDis[i] && rightDis[i]<len){
               ans[i] = 'R';
            }
            else if(leftDis[i] < rightDis[i] && leftDis[i] <len){
                ans[i] = 'L';
            }
            else ans[i] = dominoes.charAt(i);
        }
        
        return String.valueOf(ans);
        
    }

 

posted on 2019-10-03 02:14  KeepAC  阅读(142)  评论(0编辑  收藏  举报