Leetcode Test
82 删除排序链表中的重复元素Ⅱ(1.15)
给定一个已排序的链表的头 head
, 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
提示:文章来源:https://www.toymoban.com/news/detail-816097.html
- 链表中节点数目在范围
[0, 300]
内 -100 <= Node.val <= 100
- 题目数据保证链表已经按升序 排列
【模拟】
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* deleteDuplicates(struct ListNode* head) {
if(head==NULL){
return NULL;
}
struct ListNode* dummy=malloc(sizeof(struct ListNode));
dummy->next=head;
struct ListNode* cur=dummy;
while(cur->next && cur->next->next){
if(cur->next->val == cur->next->next->val){
int x=cur->next->val;
while(cur->next && cur->next->val == x){
cur->next=cur->next->next;
}
}
else{
cur=cur->next;
}
}
return dummy->next;
}
2719 统计整数数目(1.16)
给你两个数字字符串 num1
和 num2
,以及两个整数 max_sum
和 min_sum
。如果一个整数 x
满足以下条件,我们称它是一个好整数:
num1 <= x <= num2
-
min_sum <= digit_sum(x) <= max_sum
.
请你返回好整数的数目。答案可能很大,请返回答案对 109 + 7
取余后的结果。
注意,digit_sum(x)
表示 x
各位数字之和。
提示:
1 <= num1 <= num2 <= 1022
1 <= min_sum <= max_sum <= 400
【一次记忆化搜索】2719. 统计整数数目 - 力扣(LeetCode)
class Solution {
public:
int count(string num1, string num2, int min_sum, int max_sum) {
int n = num2.length();
num1 = string(n - num1.length(), '0') + num1; // 补前导零,和 num2 对齐
vector<vector<int>> memo(n, vector<int>(min(9 * n, max_sum) + 1, -1));
function<int(int, int, bool, bool)> dfs = [&](int i, int sum, bool limit_low, bool limit_high) -> int {
if (sum > max_sum) { // 非法
return 0;
}
if (i == n) {
return sum >= min_sum;
}
if (!limit_low && !limit_high && memo[i][sum] != -1) {
return memo[i][sum];
}
int lo = limit_low ? num1[i] - '0' : 0;
int hi = limit_high ? num2[i] - '0' : 9;
int res = 0;
for (int d = lo; d <= hi; d++) { // 枚举当前数位填 d
res = (res + dfs(i + 1, sum + d, limit_low && d == lo, limit_high && d == hi)) % 1'000'000'007;
}
if (!limit_low && !limit_high) {
memo[i][sum] = res;
}
return res;
};
return dfs(0, 0, true, true);
}
};
2744 最大字符串配对数目(1.17)
给你一个下标从 0 开始的数组 words
,数组中包含 互不相同 的字符串。
如果字符串 words[i]
与字符串 words[j]
满足以下条件,我们称它们可以匹配:
- 字符串
words[i]
等于words[j]
的反转字符串。 0 <= i < j < words.length
请你返回数组 words
中的 最大 匹配数目。
注意,每个字符串最多匹配一次。
提示:
1 <= words.length <= 50
words[i].length == 2
-
words
包含的字符串互不相同。 -
words[i]
只包含小写英文字母。
【暴力】
int maximumNumberOfStringPairs(char ** words, int wordsSize){
int ret=0;
for(int i=0;i<wordsSize;i++){
for(int j=i+1;j<wordsSize;j++){
if(words[i][0]==words[j][1] && words[i][1]==words[j][0]){
ret++;
}
}
}
return ret;
}
2171 拿出最少数目的魔法豆(1.18)
给定一个 正整数 数组 beans
,其中每个整数表示一个袋子里装的魔法豆的数目。
请你从每个袋子中 拿出 一些豆子(也可以 不拿出),使得剩下的 非空 袋子中(即 至少还有一颗 魔法豆的袋子)魔法豆的数目 相等。一旦把魔法豆从袋子中取出,你不能再将它放到任何袋子中。
请返回你需要拿出魔法豆的 最少数目。
提示:
1 <= beans.length <= 105
1 <= beans[i] <= 105
【数学】2171. 拿出最少数目的魔法豆 - 力扣(LeetCode)
int cmp(void *a,void *b){
return *(int*)a-*(int*)b;
}
long long minimumRemoval(int* beans, int beansSize){
qsort(beans,beansSize,sizeof(int),cmp);
long long sum=0,mx=0;
int n=beansSize;
for(int i=0;i<n;i++){
sum+=beans[i];
mx=fmax(mx,(long long)(n-i)*beans[i]);
}
return sum-mx;
}
2809 使数组和小于等于 x 的最少时间(1.19)
给你两个长度相等下标从 0 开始的整数数组 nums1
和 nums2
。每一秒,对于所有下标 0 <= i < nums1.length
,nums1[i]
的值都增加 nums2[i]
。操作 完成后 ,你可以进行如下操作:
- 选择任一满足
0 <= i < nums1.length
的下标i
,并使nums1[i] = 0
。
同时给你一个整数 x
。
请你返回使 nums1
中所有元素之和 小于等于 x
所需要的 最少 时间,如果无法实现,那么返回 -1
。
提示:
1 <= nums1.length <= 103
1 <= nums1[i] <= 103
0 <= nums2[i] <= 103
nums1.length == nums2.length
0 <= x <= 106
【动态规划】
static int cmp(const void *a, const void *b) {
return ((int *)a)[0] - ((int *)b)[0];
}
int minimumTime(int* nums1, int nums1Size, int* nums2, int nums2Size, int x) {
int n = nums1Size;
int dp[n + 1][n + 1];
int nums[n][2];
memset(dp, 0, sizeof(dp));
for (int i = 0; i < n; i++) {
nums[i][0] = nums2[i];
nums[i][1] = nums1[i];
}
qsort(nums, n, sizeof(nums[0]), cmp);
for (int j = 1; j <= n; j++) {
int b = nums[j - 1][0], a = nums[j - 1][1];
for (int i = j; i > 0; i--) {
dp[j][i] = fmax(dp[j - 1][i], dp[j - 1][i - 1] + i * b + a);
}
}
int s1 = 0, s2 = 0;
for (int i = 0; i < n; i++) {
s1 += nums1[i];
s2 += nums2[i];
}
for (int i = 0; i <= n; i++) {
if (s2 * i + s1 - dp[n][i] <= x) {
return i;
}
}
return -1;
}
2788 按分隔符拆分字符串(1.20)
给你一个字符串数组 words
和一个字符 separator
,请你按 separator
拆分 words
中的每个字符串。
返回一个由拆分后的新字符串组成的字符串数组,不包括空字符串 。
注意
-
separator
用于决定拆分发生的位置,但它不包含在结果字符串中。 - 拆分可能形成两个以上的字符串。
- 结果字符串必须保持初始相同的先后顺序。
提示:
1 <= words.length <= 100
1 <= words[i].length <= 20
-
words[i]
中的字符要么是小写英文字母,要么就是字符串".,|$#@"
中的字符(不包括引号) -
separator
是字符串".,|$#@"
中的某个字符(不包括引号)
【模拟】
class Solution {
public:
vector<string> splitWordsBySeparator(vector<string>& words, char separator) {
vector<string> ans; //结果字符串
for (auto &w : words) {
int j = 0;
//遍历当前字符串的每个字母
for (int i = 0; i <= w.size(); i++) {
//遇到分隔符或结束符, 分割字符串
if (i == w.size() || w[i] == separator) {
if (i - j > 0) {
ans.push_back(w.substr(j, i - j));
}
j = i + 1;
}
}
}
return ans;
}
};
410 分割数组的最大值(1.21)
给定一个非负整数数组 nums
和一个整数 k
,你需要将这个数组分成 k
个非空的连续子数组。
设计一个算法使得这 k
个子数组各自和的最大值最小。
提示:
1 <= nums.length <= 1000
0 <= nums[i] <= 106
1 <= k <= min(50, nums.length)
【二分 + 贪心】文章来源地址https://www.toymoban.com/news/detail-816097.html
bool check(int* nums, int numsSize, int m, int x) {
long long sum = 0;
int cnt = 1;
//x is mid figure
for (int i = 0; i < numsSize; i++) {
//surpass the mid
if (sum + nums[i] > x) {
cnt++;
sum = nums[i]; //clear the sum
}
else {
sum += nums[i];
}
}
return cnt <= m;
}
int splitArray(int* nums, int numsSize, int m) {
long long left = 0, right = 0;
for (int i = 0; i < numsSize; i++) {
right += nums[i];
left = fmax(nums[i],left);
}
//binary search
while (left < right) {
long long mid = (left + right)/2;
if (check(nums, numsSize, m, mid)) {
right = mid;
}
else {
left = mid + 1;
}
}
return left;
}
到了这里,关于【Leetcode Sheet】Weekly Practice 25的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!