Leetcode Weekly Contest 255(回溯、剪枝)

题目链接: Leetcode Weekly Contest 255

写在前面:

本次周赛做出第一题和第二题。速度太慢,目测要掉分了。

1、1979. Find Greatest Common Divisor of Array

难度:Easy

题意

求数组中最大值和最小值的最大公约数。

代码:

class Solution {
    public int findGCD(int[] nums) {
        Arrays.sort(nums);
        int min=nums[0];
        int max=nums[nums.length-1];
        return gcd(min,max);
    }
    public int gcd(int a, int b){
         if(a%b==0){
             return b;
         }
        else{
            return gcd(b,a%b);
        }
    }

}

2、1980. Find Unique Binary String

难度:Medium

题目大意:

给出n个长度为n的字符串,字符串只包含‘0’和‘1’,要求构造出一个长度为n与给定的字符串都不相同的字符串。

思路1:

用回溯法进行暴力搜索构造字符串,只要找到符合条件的答案就停止搜索。

class Solution {
    public String findDifferentBinaryString(String[] nums) {
        StringBuilder res=new StringBuilder();
        backtrack(nums,res,0);
        return res.toString();
    }
    public boolean backtrack(String[] nums,StringBuilder sb,int start){
        if(sb.length()==nums[0].length()){
            for(String s:nums){
                if(s.equals(sb.toString())){
                    return false;
                }
            }
            return true;
        }
        for(int i=start;i<nums[0].length();i++){
            char zero='0';
            sb.append(zero);
            if(backtrack(nums,sb,i+1)){
                return true;//找到一个答案就返回
            }
            sb.deleteCharAt(sb.length()-1);//回溯
            
            char one='1';
            sb.append(one);
            if(backtrack(nums,sb,i+1)){
                return true;
            }
            sb.deleteCharAt(sb.length()-1);
        }
        return false;
    }
}

思路2:

因为题目给定的字符串只有n个,可以用康托对角线定理。参考高赞回答,只要和第i个串下标i的字符nums[i][i]不同,构造出来的串就和所有的串都不同。
只限于串数不超过串长的情况。

class Solution {
    public String findDifferentBinaryString(String[] nums) {
        StringBuilder sb=new StringBuilder();
        for(int i=0;i<nums.length;i++){
            if(nums[i].charAt(i)=='0'){
                sb.append('1');
            }
            else{
                sb.append('0');
            }
        }
        return sb.toString();
    }
}

3、1981. Minimize the Difference Between Target and Chosen Elements

难度:Medium

题目大意:

从一个二维数组的每行中选一个数,要求这些数之和与目标值尽可能接近。

思路:

数据量不大,直接暴力,在穷举所有情况的过程中要剪枝。

代码

class Solution {
    public int minimizeTheDifference(int[][] mat, int target) {
        int m=mat.length;
        int n=mat[0].length;
        int minSum=0;//每行最小值之和
        for(int i=0;i<m;i++){
            int min=Integer.MAX_VALUE;
            for(int j=0;j<n;j++){
                if(mat[i][j]<min){
                    min=mat[i][j];
                }
            }
            minSum+=min;
        }
        if(minSum>=target){
            return minSum-target;
        }
        Set<Integer> prev=new HashSet<>();
        prev.add(0);
        for(int i=0;i<m;i++){
            Set<Integer> cur=new HashSet<>();
            for(int j=0;j<n;j++){
                for(int v:prev){
                    if(v+mat[i][j]-target<=target-minSum){
                        cur.add(v+mat[i][j]);
                    }
                }
            }
            prev=cur;
        }
        int res=Integer.MAX_VALUE;
        for(int v:prev){
            if(Math.abs(v-target)<res){
                res=Math.abs(v-target);
            }
        }
        return res;
    }
}

4、1982. Find Array Given Subset Sums

难度:Hard

题目大意:

详见题目。

思路

需要数学推导,不会。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值