类似于 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); }