随机练1
1004. 最大连续1的个数 III
题意: 一个01数组,求最长连续1其中可以包含k个0
分析: 双指针,建立左右指针,右指针每次向右移动,遇到0则统计zero出现的次数。如果zero > k,则移动左指针,遇到0则zero--。
class Solution {
public int longestOnes(int[] nums, int k) {
int left=0,right=0,zeros=0,len=nums.length,res=0;
while(right<len){
if(nums[right]==0) zeros++;
while(zeros>k){
if(nums[left++]==0) zeros--;
}
res=Math.max(res,right-left+1);
right++;
}
return res;
}
}
1306. 跳跃游戏 III
题意:给定一个非负整数数组,从下标start出发:下标为i的当前位置可以跳到i+nums[i] or i-nums[i]的位置。问是否可以到达元素值是0的位置。
分析:使用广度优先bfs:
start加入队列。在每一次的搜索过程中,我们取出队首的节点u,它可以到达的位置为u + arr[u]和u - arr[u]。
class Solution { public boolean canReach(int[] arr, int start) { Queue<Integer> queue= new LinkedList<>(); int len = arr.length; boolean []visited = new boolean[len]; queue.add(start); while(!queue.isEmpty()){ int x = queue.poll(); if(x+arr[x]<len&&!visited[x+arr[x]]){ if(arr[x+arr[x]]==0) return true; visited[x+arr[x]] = true; queue.add(x+arr[x]); } if(x-arr[x]>=0&&!visited[x-arr[x]]){ if(arr[x-arr[x]]==0) return true; visited[x-arr[x]]=true; queue.add(x-arr[x]); } } return false; } }
72. 编辑距离
题意:有A、B两个字符串,经过增、删、改操作 A-->B
分析:最直观的是暴力检查所有编辑方法取最短时间复杂度达到指数级,但我们只需要找到距离最短的序列而不是所有可能的序列。基于以上原则,对A,B的三种操作一共9种操作(A增加,B增加;A减少,B增加...),过滤出明显不能达到距离最短的操作(A增加,B增加;A减少,B减少;A修改,B修改)。接着我们发现,对单词
A删除一个字符和对单词B插入一个字符是等价的(doge->dog)。对单词A替换一个字符和对单词B替换一个字符是等价的(bat->cat)。这样一来,本质上能达到目的的操作就三种:1. A 增加
2. A减少(转化为B增加)
3. A修改
我们用 dp
[i][j]表示A的前i个字母和B的前j个字母之间的编辑距离。转移方程:dp[i][j]=1+min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1])
class Solution {
public int minDistance(String word1, String word2) {
int len1 = word1.length();
int len2 = word2.length();
if(len1*len2==0) return len1+len2;
int [][]dp = new int[len1+1][len2+1];
for(int i=0;i<=len1;i++) dp[i][0]=i;
for(int j=0;j<=len2;j++) dp[0][j]=j;
for(int i=0;i<len1;i++){
for(int j=0;j<len2;j++){
if(word1.charAt(i)==word2.charAt(j)) dp[i+1][j+1]=dp[i][j];
else dp[i+1][j+1]=Math.min(dp[i][j],Math.min(dp[i+1][j],dp[i][j+1]))+1;
}
}
return dp[len1][len2];
}
}

浙公网安备 33010602011771号