1662. 具有给定数值的最小字符串
a为1,z为26, 给出需要的字母个数n,和k求出满足要求的字典序最小的序列
示例 1:
输入:n = 3, k = 27
输出:“aay”
解释:字符串的数值为 1 + 1 + 25 = 27,它是数值满足要求且长度等于 3 字典序最小的字符串。
示例 2:
输入:n = 5, k = 73
输出:“aaszz”
提示:
1 <= n <= 105
n <= k <= 26 * n
Note1
- 首先想到的方法是用Dfs递归,栈爆了,数据也就过了1\7
Code1
vector<int> a;
int flag = 0;
class Solution {
public : void findnum(vector<int>path, int i, int tempsum, int cnt, int targetCnt , int target){
if(cnt == targetCnt && tempsum != target || flag == 1) return;
if(i > 26) return ;
if(tempsum == target && cnt == targetCnt){
flag = 1;
a = path;
}
path.push_back(i);
findnum(path, i, tempsum + i, cnt + 1, targetCnt, target);
path.pop_back();
findnum(path, i+1, tempsum, cnt, targetCnt, target);
}
public : string getSmallestString(int n, int k) {
vector<int> sum;
findnum(sum, 1, 0, 0, n, k);
string s;
int len = a.size();
//return to_string(len);
for(int i = 0; i < a.size(); i++) {
s += 'a' + a[i] - 1;
//s += to_string(a[i]) + " ";
}
return s;
}
};
Note2
- 题目要求的是字典序最小,则可以假设全是1,从后面开始填26,
Code2
vector<int> a;
int flag = 0;
class Solution {
public : string getSmallestString(int n, int k) {
vector<int> sum(n, 1);
int temp = n;
int i = n - 1;
while(temp < k){
if(temp + 25 < k){
sum[i] = 26;
temp += 25;
}
else{
sum[i] = k - temp + 1;
break;
}
i--;
}
string s;
for(int i = 0; i < sum.size(); i++) {
s += 'a' + sum[i] - 1;
}
return s;
}
};
1664. 生成平衡数组的方案数
给你一个整数数组 nums 。你需要选择 恰好 一个下标(下标从 0 开始)并删除对应的元素。请注意剩下元素的下标可能会因为删除操作而发生改变。
比方说,如果 nums = [6,1,7,4,1] ,那么:
选择删除下标 1 ,剩下的数组为 nums = [6,7,4,1] 。
选择删除下标 2 ,剩下的数组为 nums = [6,1,4,1] 。
选择删除下标 4 ,剩下的数组为 nums = [6,1,7,4] 。
如果一个数组满足奇数下标元素的和与偶数下标元素的和相等,该数组就是一个 平衡数组 。
请你返回删除操作后,剩下的数组 nums 是 平衡数组 的 方案数 。
示例 1:
输入:nums = [2,1,6,4]
输出:1
解释:
删除下标 0 :[1,6,4] -> 偶数元素下标为:1 + 4 = 5 。奇数元素下标为:6 。不平衡。
删除下标 1 :[2,6,4] -> 偶数元素下标为:2 + 4 = 6 。奇数元素下标为:6 。平衡。
删除下标 2 :[2,1,4] -> 偶数元素下标为:2 + 4 = 6 。奇数元素下标为:1 。不平衡。
删除下标 3 :[2,1,6] -> 偶数元素下标为:2 + 6 = 8 。奇数元素下标为:1 。不平衡。
只有一种让剩余数组成为平衡数组的方案。
示例 2:
输入:nums = [1,1,1]
输出:3
解释:你可以删除任意元素,剩余数组都是平衡数组。
示例 3:
输入:nums = [1,2,3]
输出:0
解释:不管删除哪个元素,剩下数组都不是平衡数组。
提示:
1 <= nums.length <= 105
1 <= nums[i] <= 104
Note
- 题目比较吃思路,有了上一题的经验,不上来就莽了(肯定过的点很少),想了半天发现可以将其分成未改变的奇偶部分和改变了的奇偶部分,未改变部分随着遍历的i一点点增加,改变的偶数部和奇数部分互换即可
Code1
class Solution {
public:
int waysToMakeFair(vector<int>& nums) {
int res = 0;
int sum_ji = 0, sum_ou = 0;
int l1 = 0, l2 = 0;
int r1 = 0, r2 = 0;
int len = nums.size();
for(int i = 0; i < len; ++i){
if(i % 2 == 0){
sum_ou += nums[i];
}else{
sum_ji += nums[i];
}
}
for(int i = 0; i < len; ++i){
i % 2 ? l1 += nums[i] : l2 += nums[i];
r1 = sum_ou - l2;
r2 = sum_ji-l1;
i % 2 ? r1 -= nums[i] : r2 -= nums[i];
if(l1 + r1 == l2 + r2) res++;
}
return res;
}
};
Note2
- 这里有点前缀和的感觉,时间长不练有些忘记了,即通过计算Sn = a1 + … + an使得能够在O(1)复杂度里求出am 到 an的和
Code2
class Solution {
public:
int waysToMakeFair(vector<int>& nums) {
int n = nums.size();
vector<int> s1(n + 1), s2(n + 1);
for (int i = 1; i <= n; i ++ ) {
s1[i] = s1[i - 1], s2[i] = s2[i - 1];
if (i % 2) s1[i] += nums[i - 1];
else s2[i] += nums[i - 1];
}
int res = 0;
for (int i = 1; i <= n; i ++ ) {
int odd = s1[i - 1] + s2[n] - s2[i];
int even = s2[i - 1] + s1[n] - s1[i];
if (odd == even) res ++ ;
}
return res;
}
};
1665. 完成所有任务的最少初始能量
给你一个任务数组 tasks ,其中 tasks[i] = [actuali, minimumi] :
actuali 是完成第 i 个任务 需要耗费 的实际能量。
minimumi 是开始第 i 个任务前需要达到的最低能量。
比方说,如果任务为 [10, 12] 且你当前的能量为 11 ,那么你不能开始这个任务。如果你当前的能量为 13 ,你可以完成这个任务,且完成它后剩余能量为 3 。
你可以按照 任意顺序 完成任务。
请你返回完成所有任务的 最少 初始能量。
示例 1:
输入:tasks = [[1,2],[2,4],[4,8]]
输出:8
解释:
一开始有 8 能量,我们按照如下顺序完成任务:
- 完成第 3 个任务,剩余能量为 8 - 4 = 4 。
- 完成第 2 个任务,剩余能量为 4 - 2 = 2 。
- 完成第 1 个任务,剩余能量为 2 - 1 = 1 。
注意到尽管我们有能量剩余,但是如果一开始只有 7 能量是不能完成所有任务的,因为我们无法开始第 3 个任务。
示例 2:
输入:tasks = [[1,3],[2,4],[10,11],[10,12],[8,9]]
输出:32
解释:
一开始有 32 能量,我们按照如下顺序完成任务:
- 完成第 1 个任务,剩余能量为 32 - 1 = 31 。
- 完成第 2 个任务,剩余能量为 31 - 2 = 29 。
- 完成第 3 个任务,剩余能量为 29 - 10 = 19 。
- 完成第 4 个任务,剩余能量为 19 - 10 = 9 。
- 完成第 5 个任务,剩余能量为 9 - 8 = 1 。
示例 3:
输入:tasks = [[1,7],[2,8],[3,9],[4,10],[5,11],[6,12]]
输出:27
解释:
一开始有 27 能量,我们按照如下顺序完成任务:
- 完成第 5 个任务,剩余能量为 27 - 5 = 22 。
- 完成第 2 个任务,剩余能量为 22 - 2 = 20 。
- 完成第 3 个任务,剩余能量为 20 - 3 = 17 。
- 完成第 1 个任务,剩余能量为 17 - 1 = 16 。
- 完成第 4 个任务,剩余能量为 16 - 4 = 12 。
- 完成第 6 个任务,剩余能量为 12 - 6 = 6 。
Note
- 将所需要的能量和实际需要的做差,从差最小的开始排。原因:正难则反,若完成了第i个task后能量为En(从零开始增长的),第i个task的任务能量数组为{Xi,Yi},则要满足En + Xi >= Yi 即 En >= Yi - Xi,所以要从差值小的开始,一直滚雪球到所有任务完成。
- 排序的时候,引用还是得加上,不加会超时
- 相似的题目 leetcode 502
Code1
class Solution {
public:
static bool cmp(vector<int>& a, vector<int>& b){
return a[1] - a[0] < b[1] - b[0];
}
int minimumEffort(vector<vector<int>>& tasks) {
sort(tasks.begin(), tasks.end(), cmp);
int ans = 0;
for(const auto &t:tasks){
if(ans + t[0] < t[1]) ans = t[1];
else ans += t[0];
}
return ans;
}
};