LeetCode: 第 160 场周赛题解

LeetCode: 第 160 场周赛题解

5238. 找出给定方程的正整数解

题目

给出一个函数 f(x, y) 和一个目标结果 z,请你计算方程 f(x,y) == z 所有可能的正整数 数对 x 和 y。
给定函数是严格单调的,也就是说:
f(x, y) < f(x + 1, y)
f(x, y) < f(x, y + 1)
函数接口定义如下:

interface CustomFunction {
public:
// Returns positive integer f(x, y) for any given positive integer x and y.
int f(int x, int y);
};

如果你想自定义测试,你可以输入整数 function_id 和一个目标结果 z 作为输入,其中 function_id 表示一个隐藏函数列表中的一个函数编号,题目只会告诉你列表中的 2 个函数。

你可以将满足条件的 结果数对 按任意顺序返回。

实例

示例 1:

输入:function_id = 1, z = 5
输出:[[1,4],[2,3],[3,2],[4,1]]
解释:function_id = 1 表示 f(x, y) = x + y

示例 2:

输入:function_id = 2, z = 5
输出:[[1,5],[5,1]]
解释:function_id = 2 表示 f(x, y) = x * y

题解

简单题:暴力求解,遍历所有情况即可

/*
 * // This is the custom function interface.
 * // You should not implement it, or speculate about its implementation
 * class CustomFunction {
 *     // Returns f(x, y) for any given positive integers x and y.
 *     // Note that f(x, y) is increasing with respect to both x and y.
 *     // i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
 *     public int f(int x, int y);
 * };
 */
class Solution {
    public List<List<Integer>> findSolution(CustomFunction customfunction, int z) {
        List<List<Integer>> res = new ArrayList<>();
        for(int i = 1 ; i <= 1000 ; i ++){
            for(int j = 1 ; j <= 1000; j++){
                int d = customfunction.f(i,j);
                if(d > z) break;
                else if(d == z) {
                    List<Integer> l = new ArrayList<>();
                    l.add(i);
                    l.add(j);
                    res.add(l);
                }
            }
        }
        return res;
    }
}

5239. 循环码排列

题目

给你两个整数 n 和 start。你的任务是返回任意 (0,1,2,…,2^n-1) 的排列 p,并且满足:

  • p[0] = start
  • p[i]p[i+1] 的二进制表示形式只有一位不同
  • p[0]p[2^n -1] 的二进制表示形式也只有一位不同

提示:

  • 1 <= n <= 16
  • 0 <= start < 2^n
实例

示例 1:

输入:n = 2, start = 3
输出:[3,2,0,1]
解释:这个排列的二进制表示是 (11,10,00,01)
所有的相邻元素都有一位是不同的,另一个有效的排列是 [3,1,0,2]

示例 2:

输出:n = 3, start = 2
输出:[2,6,7,5,4,0,1,3]
解释:这个排列的二进制表示是 (010,110,111,101,100,000,001,011)

题解

中等难度题。
在比赛的时候用了搜索,超时了╮(╯▽╰)╭。
其实这是一道规律题,大家可以去搜一下格雷码生成规律(•‾̑⌣‾̑•)✧˖°,下面只讲一下我用到的规律:n 位的格雷码可以由n - 1位的格雷码生成
例如 :
2 位的格雷码:
00 01 11 10
3 位的格雷码:
000 001 011 010 110 111 101 100
有下面的规律:
3 位的格雷码前四个数就是 2位格雷码
后四个数110 111 101 100 就是 逆序的 2位格雷码(10 11 01 00) 前加1。
这就可以生成n位格雷码。
题目要求从start作为第一个数,这很好办,因为格雷码是个环,遍历n位格雷码,找到start,位置前移就可以了。

class Solution {
    static boolean flag = false;
    public List<Integer> circularPermutation(int n, int start) {

        flag = false;
        int m  = 1 << n;
        int i,j;
        List<Integer> l = new ArrayList<>(m);
        List<Integer> ans = new ArrayList<>(m);
        ans.add(0);
        ans.add(1);
        for(i = 2 ; i <= n ; i ++){
            int size = ans.size();
            for(j = size - 1 ; j >= 0; j --)
                ans.add(ans.get(j) + (1 << ( i - 1)));
        }
        for( i = 0 ; i < ans.size(); i ++)
            if(ans.get(i) == start) break;
        for(j = i ; j <ans.size(); j ++) l.add(ans.get(j));
        for(j = 0 ; j < i; j ++)  l.add(ans.get(j));
        return l;
    }
}

5240. 串联字符串的最大长度

题目

给定一个字符串数组 arr,字符串 s 是将 arr 某一子序列字符串连接所得的字符串,如果 s中的每一个字符都只出现过一次,那么它就是一个可行解。
请返回所有可行解s中最长长度。

示例

示例 1:

输入:arr = [“un”,“iq”,“ue”]
输出:4
解释:所有可能的串联组合是 “”,“un”,“iq”,“ue”,“uniq” 和 “ique”,最大长度为 4。

示例 2:

输入:arr = [“cha”,“r”,“act”,“ers”]
输出:6
解释:可能的解答有 “chaers” 和 “acters”。

示例 3:

输入:arr = [“abcdefghijklmnopqrstuvwxyz”]
输出:26

提示:

  • 1 <= arr.length <= 16
  • 1 <= arr[i].length <= 26
  • arr[i] 中只含有小写英文字母
题解

中等题:DFS列出所有情况,找出符合要求的最大长度就可以。
应该还有更时间复杂度更低的算法。

class Solution {
    public int maxLength(List<String> arr) {
        List<String> ans = new ArrayList<>();
        dfs(arr,0, arr.size(),"", ans);
        Collections.sort(ans, (a,b) ->{
            return - a.length()+b.length();
        });
        int d = 0 , i = 0 , len = 0;
        for(String s: ans){
            int []a = new int[30];
            len = s.length();
            for(i = 0 ; i < len ; i ++)
                if(a[s.charAt(i) - 'a'] == 1) break;
                else a[s.charAt(i) - 'a'] =  1;
            if(i == len) {
                d = len;
                break;
            }
        }
        return d;
    }
    
    public void dfs(List arr ,int i,int n , String s, List ans){
        if(i == n){
            ans.add(s);
            return ;
        }
        dfs(arr,i + 1,n,s, ans);
        dfs(arr,i + 1,n,s + arr.get(i) , ans);
    }
}

5241. 铺瓷砖

题目

你是一位施工队的工长,根据设计师的要求准备为一套设计风格独特的房子进行室内装修。
房子的客厅大小为 n x m,为保持极简的风格,需要使用尽可能少的 正方形 瓷砖来铺盖地面。
假设正方形瓷砖的规格不限,边长都是整数。
请你帮设计师计算一下,最少需要用到多少块方形瓷砖?

实例

输入:n = 2, m = 3
输出:3
解释:3 块地砖就可以铺满卧室。
2 块 1x1 地砖
1 块 2x2 地砖

题解

高难度题,没做出来。
看了高手的答案,竟然是用打表,学到了 (…•˘_˘•…)。
还有用广搜的方法。

class Solution {
        public int tilingRectangle(int n, int m) {
        int[] a1 = {1};
        int[] a2 = {2,1};
        int[] a3 = {3,3,1};
        int[] a4 = {4,2,4,1};
        int[] a5 = {5,4,4,5,1};
        int[] a6 = {6,3,2,3,5,1};
        int[] a7 = {7,5,5,5,5,5,1};
        int[] a8 = {8,4,5,2,5,4,7,1};
        int[] a9 = {9,6,3,6,6,3,6,7,1};
        int[] a10 = {10,5,6,4,2,4,6,5,6,1};
        int[] a11 = {11,7,6,6,6,6,6,6,7,6,1};
        int[] a12 = {12,6,4,3,6,2,6,3,4,5,7,1};
        int[] a13 = {13,8,7,7,6,6,6,6,7,7,6,7,1};

        int[][] a = {a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13};
        int mx = Math.max(n, m) - 1;
        int mi = Math.min(n, m) - 1;

        return a[mx][mi];
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值