LeetCode Week Contest 141

1089. Duplicate Zeros
水题,采用暴力方法,算法复杂度为O(n^2)

class Solution {
    public void duplicateZeros(int[] arr) {
        int i=0;
        while(i<arr.length)
        {
            if(arr[i]!=0)
                i++;
            else
            {
                for(int j=arr.length-1;j>i;j--)
                    arr[j]=arr[j-1];
                i+=2;
            }
                
        }
    }
}

1090. Largest Values From Labels
这个问题的实质是贪心的选择values较大的再检查是否符合类别标签数的限制。使用优先队列以val为比较key存储这些Pair对象

class Solution {
    
    class Pair{
        
        int val;
        int label;
        
        public Pair(int val,int label){
            this.val=val;
            this.label=label;
        }
    }
    
    public int largestValsFromLabels(int[] values, int[] labels, int num_wanted, int use_limit) {
        
        PriorityQueue<Pair> pq=new PriorityQueue<>((a,b)->b.val-a.val);
        for(int i=0;i<values.length;i++)
            pq.add(new Pair(values[i],labels[i]));
        HashMap<Integer,Integer> labelCount=new HashMap<>();
        int ans=0;
        while(num_wanted>0 && !pq.isEmpty()){
            Pair tmp=pq.poll();
            int count=labelCount.getOrDefault(tmp.label,0);
            if(count<use_limit){
                ans+=tmp.val;
                num_wanted--;
                labelCount.put(tmp.label,count+1);
            }
        }
        return ans;
        
    }
}

1091. Shortest Path in Binary Matrix
经典的多源最短路径问题,头条笔试“变程序员”几乎一样,但这个问题是八连通方向。

class Solution {
    public int shortestPathBinaryMatrix(int[][] grid) {
        
        int m=grid.length,n=grid[0].length;
        if(grid[0][0]==1 || grid[m-1][n-1]==1)
            return -1;
        int[][] dist=new int[m][n];
        for(int i=0;i<m;i++)
            Arrays.fill(dist[i],-1);
        dist[0][0]=0;
        Queue<Coordinate> que=new LinkedList<>();
        que.add(new Coordinate(0,0));
        while(!que.isEmpty())
        {
            Coordinate tmp=que.poll();
            int x=tmp.x;
            int y=tmp.y;
            for(int dx=-1;dx<=1;dx++)
            {
                for(int dy=-1;dy<=1;dy++)
                {
                    if(Math.abs(dx)+Math.abs(dy)!=0 && isValid(x+dx,y+dy,grid,dist))
                    {
                        que.add(new Coordinate(x+dx,y+dy));
                        dist[x+dx][y+dy]=dist[x][y]+1;
                    }
                }
            }
        }
        return dist[m-1][n-1]==-1?-1:dist[m-1][n-1]+1;
    }
    
    public static boolean isValid(int x,int y,int grid[][],int[][] dist){
        int m=grid.length,n=grid[0].length;
        return x>=0 && x<m && y>=0 && y<n && grid[x][y]==0 && dist[x][y]==-1;
    }
    
    class Coordinate{
        int x;
        int y;
        public Coordinate(int x,int y){
            this.x=x;
            this.y=y;
        }
    }
}

1092. Shortest Common Supersequence
先找最大公共子序列LCS,再将两字符串与LCS的差集字符加到LCS中,即为最终答案。
这里说一下最长公共子序列(不连续)和最长公共字串(连续)是不一样的。最长公共子序列采用DP算法
状态转移方程为(算法导论225页):
if i=0 || j=0: dp[i,j]=0
if i,j>0 and x i = x j x_i=x_j xi=xj: dp[i,j]=dp[i-1,j-1]+1 str[i,j]=str[i-1,j-1]+ x i x_i xi
if i,j>0 and x i ! = x j x_i!=x_j xi!=xj: dp[i,j]=max(dp[i-1,j],dp[i,j-1])

class Solution {
    public String shortestCommonSupersequence(String str1, String str2) {
    
        int n=str1.length(),m=str2.length();
        String[][] dp=new String[n+1][m+1];
        for(int i=0;i<=n;i++){
            for(int j=0;j<=m;j++)
                dp[i][j]="";
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++){
                if(str1.charAt(i)==str2.charAt(j))
                    dp[i+1][j+1]=dp[i][j]+str1.charAt(i);
                else
                {
                    if(dp[i+1][j].length()>dp[i][j+1].length())
                        dp[i+1][j+1]=dp[i+1][j];
                    else
                        dp[i+1][j+1]=dp[i][j+1];
                }
                    
            }
        }
        
        String LCS=dp[n][m];
        StringBuilder sb=new StringBuilder();
        int i=0,j=0;
        for(char c:LCS.toCharArray())
        {
            while(str1.charAt(i)!=c)
            {
                sb.append(str1.charAt(i));
                i++;
            }
                
            while(str2.charAt(j)!=c)
            {
                sb.append(str2.charAt(j));
                j++;
            }
                
            sb.append(c);
            i++;
            j++;
        }
        return sb.toString()+str1.substring(i)+str2.substring(j);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值