2000. 反转单词前缀
2022.2.2 每日一题,大年初二
题目描述
给你一个下标从 0 开始的字符串 word 和一个字符 ch 。找出 ch 第一次出现的下标 i ,反转 word 中从下标 0 开始、直到下标 i 结束(含下标 i )的那段字符。如果 word 中不存在字符 ch ,则无需进行任何操作。
返回 结果字符串 。
示例 1:
示例 2:
示例 3:
提示:
思路
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 的斐波那契数字的最少数目,其中,每个斐波那契数字都可以被使用多次。
斐波那契数字定义为:
数据保证对于给定的 k ,一定能找到可行解。
示例 1:
示例 2:
示例 3:
提示:
思路
一个类似完全背包的问题,给定一堆数让找到组成一个数的最少数目,每个数字可以用多次
但是这样做明显感觉会超时,所以想想贪心的选取斐波那契数列中的数字是不是可以
看了一下示例,小的数字确实是可以贪心的选取,而大的数是由小的数组成的,应该也可以
官解的证明很严谨:
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:
示例 2:
提示:
思路
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;
}
}