面试题 01.05. 一次编辑 【中等题】【每日一题】
思路:【双指针模拟】【注解三叶】
假如一次编辑就能让两个字符串相等,那么除了这个编辑位置外的其余字符,应该对应位置是相等的。因此,字符串长度大于
1
的肯定不可能通过一次编辑实现字符串相等,直接排除。
如果first
长度大于second
,就将两个传入参数位置调换,确保第一个字符串first长度 <= second长度
。
通过指针i
表示字符串first
的字符,通过指针j
表示字符串second
的字符,同时遍历两个字符串,当i
位置字符和j
位置字符相等时,i
和j
同时右移判断下一个位置字符;否则,如果first
长度和second
长度相等,说明first
和second
如果想成功一次编辑相等,则除了这个位置之后,再不能出现字符不等的情况,于是i
和j
同时右移,且cnt++
(cnt
为异常位置数量),如果first
和second
长度不等,那么从i
位置(包括i
)往后,必须跟j
位置(不包括j
)往后字符全部相等,即这里只有j
右移1
位,cnt++
。
代码:
class Solution {
public boolean oneEditAway(String first, String second) {
int n1 = first.length(),n2 = second.length();
//如果两个字符串长度差大于1,则必不可能通过一次编辑使两个字符串相等
if (Math.abs(n1-n2)>1){
return false;
}
//保持函数的第一个参数为长度较短的字符串
if (n1 > n2){
return oneEditAway(second,first);
}
//定义第一个字符串指针 i ,第二个字符串指针 j ,异常字符数量 cnt (初值为0)
int i = 0,j = 0,cnt = 0;
//终止条件为 first 遍历结束 或者 second 遍历结束 或者 异常字符数量 大于 1 三者满足任意一个,循环都将终止
while (i < n1 && j < n2 && cnt <= 1){
//同时遍历两个字符串,求出当前位置的字符 c1 c2
char c1 = first.charAt(i),c2 = second.charAt(j);
//如果 c1 == c2 说明当前位置first和second字符相同,继续遍历两个字符串的下一个位置
if (c1 == c2){
i++;
j++;
}else {//如果 c1 != c2,说明当前位置出现异常
//如果两个字符串长度相同,那么我们想维持一次编辑就能成功,必须默认后边不可能再出现异常,于是i指针和j指针必须同时右移
if (n1 == n2){
i++;
j++;
//异常字符数量+1
cnt++;
}else {
//如果两个字符串长度不等,那么较长单词当前位置可以允许一次失误,但较短单词这个位置不能出现失误,因此j指针右移,i指针不动
j++;
//异常字符数量+1
cnt++;
}
}
}
//当循环结束后,如果此时异常字符数量小于等于1,那么说明我们可以通过一次编辑的方式实现两个字符串相同
return cnt <= 1;
}
}
剑指 Offer II 041. 滑动窗口的平均值【简单题】
思路;【队列】
定义一个队列来存储进入滑动窗口的值,每执行依次
next
,就将传入的元素值加入队列,并将值累加进sum
,当队列中元素个数大于滑动窗口长度时,将队列左端元素移除,并在sum
中减掉队列左端的元素值,next
返回sum / 队列中元素个数
,用cnt
来统计队列中的元素个数。
代码:
class MovingAverage {
int size;
int sum;
Deque<Integer> deque;
int cnt;
/** Initialize your data structure here. */
public MovingAverage(int size) {
this.deque = new ArrayDeque<>();
this.size = size;
this.sum = 0;
this.cnt = 0;
}
public double next(int val) {
deque.offer(val);
sum += val;
cnt++;
if(cnt > size){
sum -= deque.removeFirst();
}
return (double) sum / (Math.min(cnt, size));
}
}
/**
* Your MovingAverage object will be instantiated and called as such:
* MovingAverage obj = new MovingAverage(size);
* double param_1 = obj.next(val);
*/