LeetCode 2000. 反转单词前缀 / 1414. 和为 K 的最少斐波那契数字数目(贪心证明) / 1725. 可以形成最大正方形的矩形数目

2000. 反转单词前缀

2022.2.2 每日一题,大年初二

题目描述

给你一个下标从 0 开始的字符串 word 和一个字符 ch 。找出 ch 第一次出现的下标 i ,反转 word 中从下标 0 开始、直到下标 i 结束(含下标 i )的那段字符。如果 word 中不存在字符 ch ,则无需进行任何操作。

例如,如果 word = “abcdefd” 且 ch = “d” ,那么你应该 反转 从下标 0 开始、直到下标 3 结束(含下标 3 )。结果字符串将会是 “dcbaefd” 。

返回 结果字符串 。

示例 1:

输入:word = “abcdefd”, ch = “d”
输出:“dcbaefd”
解释:“d” 第一次出现在下标 3 。
反转从下标 0 到下标 3(含下标 3)的这段字符,结果字符串是 “dcbaefd” 。

示例 2:

输入:word = “xyxzxe”, ch = “z”
输出:“zxyxxe”
解释:“z” 第一次也是唯一一次出现是在下标 3 。
反转从下标 0 到下标 3(含下标 3)的这段字符,结果字符串是 “zxyxxe” 。

示例 3:

输入:word = “abcd”, ch = “z”
输出:“abcd”
解释:“z” 不存在于 word 中。
无需执行反转操作,结果字符串是 “abcd” 。

提示:

1 <= word.length <= 250
word 由小写英文字母组成
ch 是一个小写英文字母

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-prefix-of-word
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

class Solution {
    public String reversePrefix(String word, char ch) {
        int idx = 0;
        for(char c : word.toCharArray()){
            if(c == ch)
                break;
            idx++;
        }
        if(idx == word.length())
            return word;
        StringBuffer sb = new StringBuffer(word.substring(0, idx + 1));
        sb = sb.reverse();
        sb.append(word.substring(idx + 1, word.length()));
        return sb.toString();
    }
}

1414. 和为 K 的最少斐波那契数字数目

2022.2.3 每日一题

题目描述

给你数字 k ,请你返回和为 k 的斐波那契数字的最少数目,其中,每个斐波那契数字都可以被使用多次。

斐波那契数字定义为:

F1 = 1
F2 = 1
Fn = Fn-1 + Fn-2 , 其中 n > 2 。

数据保证对于给定的 k ,一定能找到可行解。

示例 1:

输入:k = 7
输出:2
解释:斐波那契数字为:1,1,2,3,5,8,13,……
对于 k = 7 ,我们可以得到 2 + 5 = 7 。

示例 2:

输入:k = 10
输出:2
解释:对于 k = 10 ,我们可以得到 2 + 8 = 10 。

示例 3:

输入:k = 19
输出:3
解释:对于 k = 19 ,我们可以得到 1 + 5 + 13 = 19 。

提示:

1 <= k <= 10^9

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-the-minimum-number-of-fibonacci-numbers-whose-sum-is-k
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

一个类似完全背包的问题,给定一堆数让找到组成一个数的最少数目,每个数字可以用多次
但是这样做明显感觉会超时,所以想想贪心的选取斐波那契数列中的数字是不是可以
看了一下示例,小的数字确实是可以贪心的选取,而大的数是由小的数组成的,应该也可以

官解的证明很严谨:
https://leetcode-cn.com/problems/find-the-minimum-number-of-fibonacci-numbers-whose-sum-is-k/solution/he-wei-k-de-zui-shao-fei-bo-na-qi-shu-zi-shu-mu-by/

证明了为什么和要求为k的时候,必须选取不大于k的数列的最大值
这样,就可以证明为什么贪心的选取是可行的

首先根据性质可以得出,选择序列中的数时,不可能是相邻的,而重复的元素也可以被不重复的元素替换
所以假设不超过k的最大数是Fm,如果不选择Fm,分奇偶性证明了所能选取的所有数的最大值小于等于Fm,也就是说必须要选择Fm才能使和等于k,也就是说必须要选择不超过k的最大的斐波那契数列的数

class Solution {
    static int bound = (int)1e9 + 7;
    static List<Integer> list = new ArrayList<>();
    static{
        int n1 = 1;
        int n2 = 1;
        list.add(1);
        list.add(1);
        while(n2 < bound){
            int temp = n1 + n2;
            list.add(temp);
            n1 = n2;
            n2 = temp;
        }
    }
    
    public int findMinFibonacciNumbers(int k) {
        //相当于完全背包问题,这么大,肯定会超时
        //是不是贪心的选取就可以呢,好像是的,因为

        int l = list.size();
        int count = 0;
        for(int i = l - 1; i >= 0; i--){
            if(list.get(i) <= k){
                k -= list.get(i);
                count++;
            }
        }
        return count;
    }
}

1725. 可以形成最大正方形的矩形数目

2022.2.4 每日一题

题目描述

给你一个数组 rectangles ,其中 rectangles[i] = [li, wi] 表示第 i 个矩形的长度为 li 、宽度为 wi 。

如果存在 k 同时满足 k <= li 和 k <= wi ,就可以将第 i 个矩形切成边长为 k 的正方形。例如,矩形 [4,6] 可以切成边长最大为 4 的正方形。

设 maxLen 为可以从矩形数组 rectangles 切分得到的 最大正方形 的边长。

请你统计有多少个矩形能够切出边长为 maxLen 的正方形,并返回矩形 数目 。

示例 1:

输入:rectangles = [[5,8],[3,9],[5,12],[16,5]]
输出:3
解释:能从每个矩形中切出的最大正方形边长分别是 [5,3,5,5] 。
最大正方形的边长为 5 ,可以由 3 个矩形切分得到。

示例 2:

输入:rectangles = [[2,3],[3,7],[4,3],[3,7]]
输出:3

提示:

1 <= rectangles.length <= 1000
rectangles[i].length == 2
1 <= li, wi <= 10^9
li != wi

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-rectangles-that-can-form-the-largest-square
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路

class Solution {
    public int countGoodRectangles(int[][] rectangles) {
        int l = rectangles.length;
        int max = 0;
        int res = 0;
        for(int i = 0; i < l; i++){
            int[] temp = rectangles[i];
            int b = Math.min(temp[0], temp[1]);
            if(b == max)
                res++;
            if(b > max){
                max = b;
                res = 1;
            }
        }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值