随机练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];
    }
}

  

posted @ 2021-07-17 15:03  petri  阅读(40)  评论(0)    收藏  举报