力扣OJ(3001-3300)

本文提供力扣在线评测平台部分精选题目解析,涵盖数组处理、链表操作、算法设计等内容,如数字统计、链表游戏、矩阵覆盖等问题,通过具体实例展示高效算法实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

3001. 捕获黑皇后需要的最少移动次数

3002. 移除后集合的最多元素数

3005. 最大频率元素计数

3011. 判断一个数组是否可以变为有序

3018. 可处理的最大删除操作数 I

3019. 按键变更的次数

3023. 在无限流中寻找模式 I

3032. 统计各位数字都不同的数字个数 II

3037. 在无限流中寻找模式 II

3038. 相同分数的最大操作数目 I

3040. 相同分数的最大操作数目 II

3046. 分割数组

3062. 链表游戏的获胜者

3063. 链表频率

3064. 使用按位查询猜测数字 I

3065. 超过阈值的最少操作数 I

3066. 超过阈值的最少操作数 II

3083. 字符串及其反转中是否存在同一子字符串

3086. 拾起 K 个 1 需要的最少行动次数

3099. 哈沙德数

3100. 换水问题 II

3111. 覆盖所有点的最少矩形数目

3115. 质数的最大距离

3116. 单面值组合的第 K 小金额

3127. 构造相同颜色的正方形

3131. 找出与数组相加的整数 I

3132. 找出与数组相加的整数 II

3133. 数组最后一个元素的最小值

3142. 判断矩阵是否满足条件

3143. 正方形中的最多点数

3146. 两个字符串的排列差

3151. 特殊数组 I

3152. 特殊数组 II

3153. 所有数对中数位差之和

3159. 查询数组中元素的出现位置

3162. 优质数对的总数 I

3176. 求出最长好子序列 I

3177. 求出最长好子序列 II

3180. 执行操作可获得的最大总奖励 I

3185. 构成整天的下标对数目 II

3191. 使二进制数组全部等于 1 的最少操作次数 I

3192. 使二进制数组全部等于 1 的最少操作次数 II

3195. 包含所有 1 的最小矩形面积 I

3206. 交替组 I

3208. 交替组 II

3211. 生成不含相邻零的二进制字符串

3216. 交换后字典序最小的字符串

3217. 从链表中移除在数组中存在的节点

3218. 切蛋糕的最小总开销 I

3219. 切蛋糕的最小总开销 II

3222. 求出硬币游戏的赢家

3226. 使两个整数相等的位更改次数

3232. 判断是否可以赢得数字游戏

3238. 求出胜利玩家的数目

3239. 最少翻转次数使二进制矩阵回文 I

3240. 最少翻转次数使二进制矩阵回文 II

3242. 设计相邻元素求和服务

3248. 矩阵中的蛇

3249. 统计好节点的数目

3250. 单调数组对的数目 I

3251. 单调数组对的数目 II

3254. 长度为 K 的子数组的能量值 I

3255. 长度为 K 的子数组的能量值 II

3258. 统计满足 K 约束的子字符串数量 I

3259. 超级饮料的最大强化能量

3261. 统计满足 K 约束的子字符串数量 II

3264. K 次乘运算后的最终数组 I

3266. K 次乘运算后的最终数组 II

3270. 求出数字答案

3274. 检查棋盘方格颜色是否相同

3285. 找到稳定山的下标


3001. 捕获黑皇后需要的最少移动次数

现有一个下标从 1 开始的 8 x 8 棋盘,上面有 3 枚棋子。

给你 6 个整数 a 、b 、c 、d 、e 和 f ,其中:

  • (a, b) 表示白色车的位置。
  • (c, d) 表示白色象的位置。
  • (e, f) 表示黑皇后的位置。

假定你只能移动白色棋子,返回捕获黑皇后所需的最少移动次数。

请注意

  • 车可以向垂直或水平方向移动任意数量的格子,但不能跳过其他棋子。
  • 象可以沿对角线方向移动任意数量的格子,但不能跳过其他棋子。
  • 如果车或象能移向皇后所在的格子,则认为它们可以捕获皇后。
  • 皇后不能移动。

示例 1:

输入:a = 1, b = 1, c = 8, d = 8, e = 2, f = 3
输出:2
解释:将白色车先移动到 (1, 3) ,然后移动到 (2, 3) 来捕获黑皇后,共需移动 2 次。
由于起始时没有任何棋子正在攻击黑皇后,要想捕获黑皇后,移动次数不可能少于 2 次。

示例 2:

输入:a = 5, b = 3, c = 3, d = 4, e = 5, f = 2
输出:1
解释:可以通过以下任一方式移动 1 次捕获黑皇后:
- 将白色车移动到 (5, 2) 。
- 将白色象移动到 (5, 2) 。

提示:

  • 1 <= a, b, c, d, e, f <= 8
  • 两枚棋子不会同时出现在同一个格子上。

class Solution {
public:
	int minMovesToCaptureTheQueen(int a, int b, int c, int d, int e, int f) {
		Point p1(a, b), p2(c, d), p3(e, f);
		if ((a == e || b == f)&&(!IsPointInLine(Line(p1,p3),p2)||!PointInSegment(p1,p3,p2))) return 1;
		if ((c + d == e + f || c - d == e - f)&&(!IsPointInLine(Line(p2, p3), p1)|| !PointInSegment(p2, p3, p1)))return 1;
		return 2;
	}
};

3002. 移除后集合的最多元素数

给你两个下标从 0 开始的整数数组 nums1 和 nums2 ,它们的长度都是偶数 n 。

你必须从 nums1 中移除 n / 2 个元素,同时从 nums2 中也移除 n / 2 个元素。移除之后,你将 nums1 和 nums2 中剩下的元素插入到集合 s 中。

返回集合 s可能的 最多 包含多少元素。

示例 1:

输入:nums1 = [1,2,1,2], nums2 = [1,1,1,1]
输出:2
解释:从 nums1 和 nums2 中移除两个 1 。移除后,数组变为 nums1 = [2,2] 和 nums2 = [1,1] 。因此,s = {1,2} 。
可以证明,在移除之后,集合 s 最多可以包含 2 个元素。

示例 2:

输入:nums1 = [1,2,3,4,5,6], nums2 = [2,3,2,3,2,3]
输出:5
解释:从 nums1 中移除 2、3 和 6 ,同时从 nums2 中移除两个 3 和一个 2 。移除后,数组变为 nums1 = [1,4,5] 和 nums2 = [2,3,2] 。因此,s = {1,2,3,4,5} 。
可以证明,在移除之后,集合 s 最多可以包含 5 个元素。 

示例 3:

输入:nums1 = [1,1,2,2,3,3], nums2 = [4,4,5,5,6,6]
输出:6
解释:从 nums1 中移除 1、2 和 3 ,同时从 nums2 中移除 4、5 和 6 。移除后,数组变为 nums1 = [1,2,3] 和 nums2 = [4,5,6] 。因此,s = {1,2,3,4,5,6} 。
可以证明,在移除之后,集合 s 最多可以包含 6 个元素。 

提示:

  • n == nums1.length == nums2.length
  • 1 <= n <= 2 * 104
  • n是偶数。
  • 1 <= nums1[i], nums2[i] <= 109
class Solution {
public:
	int maximumSetSize(vector<int>& nums1, vector<int>& nums2) {
		set<int>s1, s2, s3;
		int s = 0;
		for (auto x : nums1)s1.insert(x);
		for (auto x : nums2) {
			s2.insert(x);
			if (s1.find(x) != s1.end())s3.insert(x);
		}
		int a = s3.size(), n = nums1.size() / 2;
		int b = s1.size() - a, c = s2.size() - a;
		return min(min(b, n) + min(c, n) + a, n + n);
	}
};

3005. 最大频率元素计数

给你一个由 正整数 组成的数组 nums 。

返回数组 nums 中所有具有 最大 频率的元素的 总频率 

元素的 频率 是指该元素在数组中出现的次数。

示例 1:

输入:nums = [1,2,2,3,1,4]
输出:4
解释:元素 1 和 2 的频率为 2 ,是数组中的最大频率。
因此具有最大频率的元素在数组中的数量是 4 。

示例 2:

输入:nums = [1,2,3,4,5]
输出:5
解释:数组中的所有元素的频率都为 1 ,是最大频率。
因此具有最大频率的元素在数组中的数量是 5 。

提示:

  • 1 <= nums.length <= 100
  • 1 <= nums[i] <= 100
class Solution {
public:
	int maxFrequencyElements(vector<int>& nums) {
		map<int, int>m;
		int s = 0, num = 0;
		for (auto x : nums)s = max(s, ++m[x]);
		for (auto mi : m)if (mi.second == s)num++;
		return num * s;
	}
};

3011. 判断一个数组是否可以变为有序

双指针

3018. 可处理的最大删除操作数 I

区间DP

3019. 按键变更的次数

给你一个下标从 0 开始的字符串 s ,该字符串由用户输入。按键变更的定义是:使用与上次使用的按键不同的键。例如 s = "ab" 表示按键变更一次,而 s = "bBBb" 不存在按键变更。

返回用户输入过程中按键变更的次数。

注意:shift 或 caps lock 等修饰键不计入按键变更,也就是说,如果用户先输入字母 'a' 然后输入字母 'A' ,不算作按键变更。

示例 1:

输入:s = "aAbBcC"
输出:2
解释: 
从 s[0] = 'a' 到 s[1] = 'A',不存在按键变更,因为不计入 caps lock 或 shift 。
从 s[1] = 'A' 到 s[2] = 'b',按键变更。
从 s[2] = 'b' 到 s[3] = 'B',不存在按键变更,因为不计入 caps lock 或 shift 。
从 s[3] = 'B' 到 s[4] = 'c',按键变更。
从 s[4] = 'c' 到 s[5] = 'C',不存在按键变更,因为不计入 caps lock 或 shift 。

示例 2:

输入:s = "AaAaAaaA"
输出:0
解释: 不存在按键变更,因为这个过程中只按下字母 'a' 和 'A' ,不需要进行按键变更。

提示:

  • 1 <= s.length <= 100
  • s 仅由英文大写字母和小写字母组成。
class Solution {
public:
	int countKeyChanges(string s) {
		s[0] = tolower(s[0]);
		int ans = 0;
		for (int i = 1; i < s.length(); i++) {
			s[i] = tolower(s[i]);
			if (s[i] != s[i - 1])ans++;
		}
		return ans;
	}
};

3023. 在无限流中寻找模式 I

状态压缩

3032. 统计各位数字都不同的数字个数 II

给你两个 正整数 a 和 b ,返回 闭区间 [a, b] 内各位数字都不同的数字个数。

示例 1:

输入:a = 1, b = 20
输出:19
解释:除 11 以外,区间 [1, 20] 内的所有数字的各位数字都不同。因此,答案为 19 。

示例 2:

输入:a = 9, b = 19
输出:10
解释:除 11 以外,区间 [1, 20] 内的所有数字的各位数字都不同。因此,答案为 10 。

示例 3:

输入:a = 80, b = 120
输出:27
解释:区间 [80, 120] 内共有 41 个整数,其中 27 个数字的各位数字都不同。

提示:

  • 1 <= a <= b <= 1000
class Solution {
public:
	int numberCount(int a, int b) {
		int n = 0;
		for (int i = a; i <= b; i++)if (check(i))n++;
		return n;
	}
	bool check(int x) {
		set<int>s;
		int n = 0;
		while (x)s.insert(x % 10), x /= 10, n++;
		return n == s.size();
	}
};

3037. 在无限流中寻找模式 II

KMP

3038. 相同分数的最大操作数目 I

给你一个整数数组 nums ,如果 nums 至少 包含 2 个元素,你可以执行以下操作:

  • 选择 nums 中的前两个元素并将它们删除。

一次操作的 分数 是被删除元素的和。

在确保 所有操作分数相同 的前提下,请你求出 最多 能进行多少次操作。

请你返回按照上述要求 最多 可以进行的操作次数。

示例 1:

输入:nums = [3,2,1,4,5]
输出:2
解释:我们执行以下操作:
- 删除前两个元素,分数为 3 + 2 = 5 ,nums = [1,4,5] 。
- 删除前两个元素,分数为 1 + 4 = 5 ,nums = [5] 。
由于只剩下 1 个元素,我们无法继续进行任何操作。

示例 2:

输入:nums = [3,2,6,1,4]
输出:1
解释:我们执行以下操作:
- 删除前两个元素,分数为 3 + 2 = 5 ,nums = [6,1,4] 。
由于下一次操作的分数与前一次不相等,我们无法继续进行任何操作。

提示:

  • 2 <= nums.length <= 100
  • 1 <= nums[i] <= 1000
class Solution {
public:
    int maxOperations(vector<int>& nums) {
        int ans=1,s=nums[0]+nums[1];
        for(int i=3;i<nums.size();i+=2){
            if(nums[i]+nums[i-1]-s)break;
            ans++;
        }
        return ans;
    }
};

3040. 相同分数的最大操作数目 II

给你一个整数数组 nums ,如果 nums 至少 包含 2 个元素,你可以执行以下操作中的 任意 一个:

  • 选择 nums 中最前面两个元素并且删除它们。
  • 选择 nums 中最后两个元素并且删除它们。
  • 选择 nums 中第一个和最后一个元素并且删除它们。

一次操作的 分数 是被删除元素的和。

在确保 所有操作分数相同 的前提下,请你求出 最多 能进行多少次操作。

请你返回按照上述要求 最多 可以进行的操作次数。

示例 1:

输入:nums = [3,2,1,2,3,4]
输出:3
解释:我们执行以下操作:
- 删除前两个元素,分数为 3 + 2 = 5 ,nums = [1,2,3,4] 。
- 删除第一个元素和最后一个元素,分数为 1 + 4 = 5 ,nums = [2,3] 。
- 删除第一个元素和最后一个元素,分数为 2 + 3 = 5 ,nums = [] 。
由于 nums 为空,我们无法继续进行任何操作。

示例 2:

输入:nums = [3,2,6,1,4]
输出:2
解释:我们执行以下操作:
- 删除前两个元素,分数为 3 + 2 = 5 ,nums = [6,1,4] 。
- 删除最后两个元素,分数为 1 + 4 = 5 ,nums = [6] 。
至多进行 2 次操作。

提示:

  • 2 <= nums.length <= 2000
  • 1 <= nums[i] <= 1000
class Solution {
public:
    int maxOperations(vector<int>& nums) {
        int s1=nums[0]+nums[1],s2=nums[0]+nums[nums.size()-1],s3=nums[nums.size()-2]+nums[nums.size()-1];
        int ans=maxOperations(nums,s1);
        if(s2!=s1)ans=max(ans,maxOperations(nums,s2));
        if(s3!=s1 && s3!=s2)ans=max(ans,maxOperations(nums,s3));
        return ans;
    }
    int maxOperations(vector<int>& nums,int s) {
        m.clear();
        return maxOperations(nums,0,nums.size()-1,s);
    }
    int maxOperations(vector<int>& nums,int low,int high,int s) {
        if(m[low].find(high)!=m[low].end())return m[low][high];
        if(low>=high)return 0;
        int ans=0;
        if(nums[low]+nums[low+1]==s)ans=maxOperations(nums,low+2,high,s)+1;
        if(nums[high]+nums[high-1]==s)ans=max(ans,maxOperations(nums,low,high-2,s)+1);
        if(nums[low]+nums[high]==s)ans=max(ans,maxOperations(nums,low+1,high-1,s)+1);
        return m[low][high]=ans;
    }
    unordered_map<int,unordered_map<int,int>>m;
};

3046. 分割数组

给你一个长度为 偶数 的整数数组 nums 。你需要将这个数组分割成 nums1 和 nums2 两部分,要求:

  • nums1.length == nums2.length == nums.length / 2 。
  • nums1 应包含 互不相同 的元素。
  • nums2也应包含 互不相同 的元素。

如果能够分割数组就返回 true ,否则返回 false 。

示例 1:

输入:nums = [1,1,2,2,3,4]
输出:true
解释:分割 nums 的可行方案之一是 nums1 = [1,2,3] 和 nums2 = [1,2,4] 。

示例 2:

输入:nums = [1,1,1,1]
输出:false
解释:分割 nums 的唯一可行方案是 nums1 = [1,1] 和 nums2 = [1,1] 。但 nums1 和 nums2 都不是由互不相同的元素构成。因此,返回 false 。

提示:

  • 1 <= nums.length <= 100
  • nums.length % 2 == 0
  • 1 <= nums[i] <= 100
class Solution {
public:
	bool isPossibleToSplit(vector<int>& nums) {
		sort(nums.begin(), nums.end());
		for (int i = 2; i < nums.size(); i++) {
			if (nums[i] == nums[i - 2])return false;
		}
		return true;
	}
};

3062. 链表游戏的获胜者

给定长度为 偶数 ,包含整数的链表的 head 节点。

每个 奇数编号 的节点包含一个奇数,并且每个 偶数编号 的节点包含一个偶数。

我们把每个偶数编号的节点和它的下一个节点叫做一个 ,例如编号为 0 和 1 的节点是一对,编号为 2 和 3 的节点是一对,以此类推。

对于每个 ,我们比较对中节点的值:

  • 如果奇数节点更大,"Odd" 队得一分。
  • 如果偶数节点更大,"Even" 队得一分。

返回分数更  的队名,如果分数相同,返回 "Tie"

示例 1:

输入:head = [2,1]
输出:"Even"
解释:链表中只有一个对 (2,1)。因为 2 > 1,偶数队得分。
因此,答案是 "Even"。

示例 2:

输入:head = [2,5,4,7,20,5] 
输出:"Odd" 
解释:此链表中有 3 对。让我们分别对每一对进行分析: 
(2,5) -> 因为 2 < 5,奇数队得分。
(4,7) -> 因为 4 < 7,奇数队得分。 
(20,5) -> 因为 20 > 5,偶数队得分。 
奇数队得 2 分,偶数队得 1 分,奇数队得分更高。 
因此,答案是 "Odd"。

示例 3:

输入:head = [4,5,2,1]
输出:"Tie"
解释:此链表中有 2 对。让我们分别对每一对进行分析:
(4,5) -> 因为 4 < 5,奇数队得分。
(2,1) -> 因为 2 > 1,偶数队得分。
每队得 1 分。
因此,答案是 "Tie"。

提示:

  • 链表中节点的数字在范围 [2, 100] 内。
  • 链表中的节点数为偶数。
  • 1 <= Node.val <= 100
  • 每个奇数编号节点的值都是奇数。
  • 每个偶数编号节点的值都是偶数。

class Solution {
public:
    string gameResult(ListNode* head) {
        int s=0;
        while(head){
            int a=head->val;
            head=head->next;
            a-=head->val;
            head=head->next;
            if(a>0)s++;
            else s--;
        }
        if(s>0)return "Even";
        if(s<0)return "Odd";
        return "Tie";
    }
};

3063. 链表频率

单链表

3064. 使用按位查询猜测数字 I

位运算

3065. 超过阈值的最少操作数 I

给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。

一次操作中,你可以删除 nums 中的最小元素。

你需要使数组中的所有元素都大于或等于 k ,请你返回需要的 最少 操作次数。

示例 1:

输入:nums = [2,11,10,1,3], k = 10
输出:3
解释:第一次操作后,nums 变为 [2, 11, 10, 3] 。
第二次操作后,nums 变为 [11, 10, 3] 。
第三次操作后,nums 变为 [11, 10] 。
此时,数组中的所有元素都大于等于 10 ,所以我们停止操作。
使数组中所有元素都大于等于 10 需要的最少操作次数为 3 。

示例 2:

输入:nums = [1,1,2,4,9], k = 1
输出:0
解释:数组中的所有元素都大于等于 1 ,所以不需要对 nums 做任何操作。

示例 3:

输入:nums = [1,1,2,4,9], k = 9
输出:4
解释:nums 中只有一个元素大于等于 9 ,所以需要执行 4 次操作。

提示:

  • 1 <= nums.length <= 50
  • 1 <= nums[i] <= 109
  • 1 <= k <= 109
  • 输入保证至少有一个满足 nums[i] >= k 的下标 i 存在。
class Solution {
public:
    int minOperations(vector<int>& nums, int k) {
        int s=0;
        for(auto x:nums)s+=(x<k);
        return s;
    }
};

3066. 超过阈值的最少操作数 II

给你一个下标从 0 开始的整数数组 nums 和一个整数 k 。

一次操作中,你将执行:

  • 选择 nums 中最小的两个整数 x 和 y 。
  • 将 x 和 y 从 nums 中删除。
  • 将 min(x, y) * 2 + max(x, y) 添加到数组中的任意位置。

注意,只有当 nums 至少包含两个元素时,你才可以执行以上操作。

你需要使数组中的所有元素都大于或等于 k ,请你返回需要的 最少 操作次数。

示例 1:

输入:nums = [2,11,10,1,3], k = 10
输出:2
解释:第一次操作中,我们删除元素 1 和 2 ,然后添加 1 * 2 + 2 到 nums 中,nums 变为 [4, 11, 10, 3] 。
第二次操作中,我们删除元素 3 和 4 ,然后添加 3 * 2 + 4 到 nums 中,nums 变为 [10, 11, 10] 。
此时,数组中的所有元素都大于等于 10 ,所以我们停止操作。
使数组中所有元素都大于等于 10 需要的最少操作次数为 2 。

示例 2:

输入:nums = [1,1,2,4,9], k = 20
输出:4
解释:第一次操作后,nums 变为 [2, 4, 9, 3] 。
第二次操作后,nums 变为 [7, 4, 9] 。
第三次操作后,nums 变为 [15, 9] 。
第四次操作后,nums 变为 [33] 。
此时,数组中的所有元素都大于等于 20 ,所以我们停止操作。
使数组中所有元素都大于等于 20 需要的最少操作次数为 4 。

提示:

  • 2 <= nums.length <= 2 * 105
  • 1 <= nums[i] <= 109
  • 1 <= k <= 109
  • 输入保证答案一定存在,也就是说一定存在一个操作序列使数组中所有元素都大于等于 k 。
class Solution {
public:
	int minOperations(vector<int>& nums, int k) {
		int ans = 0;
		priority_queue<long long, vector<long long>, greater<long long>>q;
		for (auto x : nums)q.push(x);
		while (q.size() > 1) {
			long long a = q.top();
			q.pop();
			if (a >= k)return ans;
			long long b = q.top();
			q.pop();
			q.push(a + a + b);
			ans++;
		}
		return ans;
	}
};

3083. 字符串及其反转中是否存在同一子字符串

给你一个字符串 s ,请你判断字符串 s 是否存在一个长度为 2 的子字符串,在 s 反转后的字符串中也出现。

如果存在这样的子字符串,返回 true;如果不存在,返回 false 。

示例 1:

输入:s = "leetcode"

输出:true

解释:子字符串 "ee" 的长度为 2,它也出现在 reverse(s) == "edocteel" 中。

示例 2:

输入:s = "abcba"

输出:true

解释:所有长度为 2 的子字符串 "ab""bc""cb""ba" 也都出现在 reverse(s) == "abcba" 中。

示例 3:

输入:s = "abcd"

输出:false

解释:字符串 s 中不存在满足「在其反转后的字符串中也出现」且长度为 2 的子字符串。

提示:

  • 1 <= s.length <= 100
  • 字符串 s 仅由小写英文字母组成。
class Solution {
public:
	bool isSubstringPresent(string s) {
		string empt;
		set<string>se;
		for (int i = 1; i < s.length(); i++) {
			if (s[i] == s[i - 1])return true;
			if(se.find(empt + s[i] + s[i - 1])!=se.end())return true;
			se.insert(empt + s[i - 1] + s[i]);
		}
		return false;
	}
};

3086. 拾起 K 个 1 需要的最少行动次数

给你一个下标从 0 开始的二进制数组 nums,其长度为 n ;另给你一个 正整数 k 以及一个 非负整数 maxChanges 。

Alice 在玩一个游戏,游戏的目标是让 Alice 使用 最少 数量的 行动 次数从 nums 中拾起 k 个 1 。游戏开始时,Alice 可以选择数组 [0, n - 1] 范围内的任何索引 aliceIndex 站立。如果 nums[aliceIndex] == 1 ,Alice 会拾起一个 1 ,并且 nums[aliceIndex] 变成0(这 不算 作一次行动)。之后,Alice 可以执行 任意数量 的 行动包括零次),在每次行动中 Alice 必须 恰好 执行以下动作之一:

  • 选择任意一个下标 j != aliceIndex 且满足 nums[j] == 0 ,然后将 nums[j] 设置为 1 。这个动作最多可以执行 maxChanges 次。
  • 选择任意两个相邻的下标 x 和 y|x - y| == 1)且满足 nums[x] == 1nums[y] == 0 ,然后交换它们的值(将 nums[y] = 1 和 nums[x] = 0)。如果 y == aliceIndex,在这次行动后 Alice 拾起一个 1 ,并且 nums[y] 变成 0 。

返回 Alice 拾起 恰好 k 个 1 所需的 最少 行动次数。

示例 1:

输入:nums = [1,1,0,0,0,1,1,0,0,1], k = 3, maxChanges = 1

输出:3

解释:如果游戏开始时 Alice 在 aliceIndex == 1 的位置上,按照以下步骤执行每个动作,他可以利用 3 次行动拾取 3 个 1 :

  • 游戏开始时 Alice 拾取了一个 1 ,nums[1] 变成了 0。此时 nums 变为 [1,0,1,0,0,1,1,0,0,1] 。
  • 选择 j == 2 并执行第一种类型的动作。nums 变为 [1,0,1,0,0,1,1,0,0,1]
  • 选择 x == 2 和 y == 1 ,并执行第二种类型的动作。nums 变为 [1,1,0,0,0,1,1,0,0,1] 。由于 y == aliceIndex,Alice 拾取了一个 1 ,nums 变为  [1,0,0,0,0,1,1,0,0,1] 。
  • 选择 x == 0 和 y == 1 ,并执行第二种类型的动作。nums 变为 [0,1,0,0,0,1,1,0,0,1] 。由于 y == aliceIndex,Alice 拾取了一个 1 ,nums 变为  [0,0,0,0,0,1,1,0,0,1] 。

请注意,Alice 也可能执行其他的 3 次行动序列达成拾取 3 个 1 。

示例 2:

输入:nums = [0,0,0,0], k = 2, maxChanges = 3

输出:4

解释:如果游戏开始时 Alice 在 aliceIndex == 0 的位置上,按照以下步骤执行每个动作,他可以利用 4 次行动拾取 2 个 1 :

  • 选择 j == 1 并执行第一种类型的动作。nums 变为 [0,1,0,0] 。
  • 选择 x == 1 和 y == 0 ,并执行第二种类型的动作。nums 变为 [1,0,0,0] 。由于 y == aliceIndex,Alice 拾起了一个 1 ,nums 变为 [0,0,0,0] 。
  • 再次选择 j == 1 并执行第一种类型的动作。nums 变为 [0,1,0,0] 。
  • 再次选择 x == 1 和 y == 0 ,并执行第二种类型的动作。nums 变为 [1,0,0,0] 。由于y == aliceIndex,Alice 拾起了一个 1 ,nums 变为 [0,0,0,0] 。

提示:

  • 2 <= n <= 105
  • 0 <= nums[i] <= 1
  • 1 <= k <= 105
  • 0 <= maxChanges <= 105
  • maxChanges + sum(nums) >= k
class Solution {
public:
	long long minimumMoves(vector<int>& nums, int k, int maxChanges) {
		int loc = near3(nums);
		int s = s3(nums, loc);
        if (k == 1)return s?0:2;
		if (k <= s) return k - nums[loc];
		if (k <= s + maxChanges)return k * 2 - s - nums[loc];
		return minimumMoves(nums, k - maxChanges) + maxChanges * 2;
	}
	long long minimumMoves(vector<int>& nums, int k) // maxChanges=0
	{
		deque<int>q;
		long long s = 0, ans = 0;
		for (int i = 0; i < nums.size(); i++)
		{
			if (nums[i] == 0)continue;
			q.push_back(i);
			if (q.size() == k) {
				int m = q[k / 2];
				for (int i = 0; i < k; i++) {
					s += abs(q[i] - m);
				}
				ans = s;
			}
			if (q.size() > k) {
				s += abs(q[k] - q[(k + 1) / 2]) - abs(q[0] - q[k / 2]);
				ans = min(ans, s);
				q.pop_front();
			}
		}
		return ans;
	}
	int s3(vector<int>& nums, int id)
	{
		int s = nums[id];
		if (id)s += nums[id - 1];
		if (id + 1 < nums.size())s += nums[id + 1];
		return s;
	}
	int near3(vector<int>& nums)
	{
		int loc = 0, smax = 0;
		for (int i = 0; i < nums.size(); i++) {
			int s = s3(nums, i);
			if (smax < s)smax = s, loc = i;
			if (smax == s && nums[i])loc = i;
		}
		return loc;
	}
};

3099. 哈沙德数

如果一个整数能够被其各个数位上的数字之和整除,则称之为 哈沙德数(Harshad number)。给你一个整数 x 。如果 x 是 哈沙德数 ,则返回 x 各个数位上的数字之和,否则,返回 -1 。

示例 1:

输入: x = 18

输出: 9

解释:

x 各个数位上的数字之和为 9 。18 能被 9 整除。因此 18 是哈沙德数,答案是 9 。

示例 2:

输入: x = 23

输出: -1

解释:

x 各个数位上的数字之和为 5 。23 不能被 5 整除。因此 23 不是哈沙德数,答案是 -1 。

提示:

  • 1 <= x <= 100
class Solution {
public:
    int sumOfTheDigitsOfHarshadNumber(int x) {
        int s=0,y=x;
        while(y)s+=y%10,y/=10;
        if(x%s==0)return s;
        return -1;
    }
};

3100. 换水问题 II

给你两个整数 numBottles 和 numExchange 。

numBottles 代表你最初拥有的满水瓶数量。在一次操作中,你可以执行以下操作之一:

  • 喝掉任意数量的满水瓶,使它们变成空水瓶。
  • 用 numExchange 个空水瓶交换一个满水瓶。然后,将 numExchange 的值增加 1 。

注意,你不能使用相同的 numExchange 值交换多批空水瓶。例如,如果 numBottles == 3 并且 numExchange == 1 ,则不能用 3 个空水瓶交换成 3 个满水瓶。

返回你 最多 可以喝到多少瓶水。

示例 1:

输入:numBottles = 13, numExchange = 6
输出:15
解释:上表显示了满水瓶的数量、空水瓶的数量、numExchange 的值,以及累计喝掉的水瓶数量。

示例 2:

输入:numBottles = 10, numExchange = 3
输出:13
解释:上表显示了满水瓶的数量、空水瓶的数量、numExchange 的值,以及累计喝掉的水瓶数量。

提示:

  • 1 <= numBottles <= 100
  • 1 <= numExchange <= 100
class Solution {
public:
    int maxBottlesDrunk(int numBottles, int numExchange) {
        int ans=numBottles,s=numBottles;
        while(s>=numExchange){
            s-=numExchange++-1;
            ans++;
        }
        return ans;
    }
};

3110. 字符串的分数

给你一个字符串 s 。一个字符串的 分数 定义为相邻字符 ASCII 码差值绝对值的和。

请你返回 s 的 分数 。

示例 1:

输入:s = "hello"

输出:13

解释:

s 中字符的 ASCII 码分别为:'h' = 104 ,'e' = 101 ,'l' = 108 ,'o' = 111 。所以 s 的分数为 |104 - 101| + |101 - 108| + |108 - 108| + |108 - 111| = 3 + 7 + 0 + 3 = 13 。

示例 2:

输入:s = "zaz"

输出:50

解释:

s 中字符的 ASCII 码分别为:'z' = 122 ,'a' = 97 。所以 s 的分数为 |122 - 97| + |97 - 122| = 25 + 25 = 50 。

提示:

  • 2 <= s.length <= 100
  • s 只包含小写英文字母。
class Solution {
public:
    int scoreOfString(string s) {
        char c=s[0];
        int ans=0;
        for(auto ch:s)ans+=abs(ch-c),c=ch;
        return ans;
    }
};

3111. 覆盖所有点的最少矩形数目

给你一个二维整数数组 point ,其中 points[i] = [xi, yi] 表示二维平面内的一个点。同时给你一个整数 w 。你需要用矩形 覆盖所有 点。

每个矩形的左下角在某个点 (x1, 0) 处,且右上角在某个点 (x2, y2) 处,其中 x1 <= x2 且 y2 >= 0 ,同时对于每个矩形都 必须 满足 x2 - x1 <= w 。

如果一个点在矩形内或者在边上,我们说这个点被矩形覆盖了。

请你在确保每个点都 至少 被一个矩形覆盖的前提下,最少 需要多少个矩形。

注意:一个点可以被多个矩形覆盖。

示例 1:

输入:points = [[2,1],[1,0],[1,4],[1,8],[3,5],[4,6]], w = 1

输出:2

解释:

上图展示了一种可行的矩形放置方案:

  • 一个矩形的左下角在 (1, 0) ,右上角在 (2, 8) 。
  • 一个矩形的左下角在 (3, 0) ,右上角在 (4, 8) 。

示例 2:

输入:points = [[0,0],[1,1],[2,2],[3,3],[4,4],[5,5],[6,6]], w = 2

输出:3

解释:

上图展示了一种可行的矩形放置方案:

  • 一个矩形的左下角在 (0, 0) ,右上角在 (2, 2) 。
  • 一个矩形的左下角在 (3, 0) ,右上角在 (5, 5) 。
  • 一个矩形的左下角在 (6, 0) ,右上角在 (6, 6) 。

示例 3:

输入:points = [[2,3],[1,2]], w = 0

输出:2

解释:

上图展示了一种可行的矩形放置方案:

  • 一个矩形的左下角在 (1, 0) ,右上角在 (1, 2) 。
  • 一个矩形的左下角在 (2, 0) ,右上角在 (2, 3) 。

提示:

  • 1 <= points.length <= 105
  • points[i].length == 2
  • 0 <= xi == points[i][0] <= 109
  • 0 <= yi == points[i][1] <= 109
  • 0 <= w <= 109
  • 所有点坐标 (xi, yi) 互不相同。

class Solution {
public:
	int minRectanglesToCoverPoints(vector<vector<int>>& points, int w) {
		vector<int>v;
		for (auto vi : points)v.push_back(vi[0]);
		sort(v.begin(), v.end());
		int x = v[0], ans = 1;
		for (int i = 0; i < v.size(); i++) {
			if (v[i] - x > w)ans++, x = v[i];
		}
		return ans;
	}
};

3115. 质数的最大距离

素数检测

3116. 单面值组合的第 K 小金额

容斥原理

3120. 统计特殊字母的数量 I

给你一个字符串 word。如果 word 中同时存在某个字母的小写形式和大写形式,则称这个字母为 特殊字母 。

返回 word 中 特殊字母 的数量。

示例 1:

输入:word = "aaAbcBC"

输出:3

解释:

word 中的特殊字母是 'a''b' 和 'c'

示例 2:

输入:word = "abc"

输出:0

解释:

word 中不存在大小写形式同时出现的字母。

示例 3:

输入:word = "abBCab"

输出:1

解释:

word 中唯一的特殊字母是 'b'

提示:

  • 1 <= word.length <= 50
  • word 仅由小写和大写英文字母组成。
class Solution {
public:
    int numberOfSpecialChars(string word) {
        int num[52];
        for(int i=0;i<52;i++)num[i]=0;
        for(auto c:word){
            if(c>='a'&&c<='z')num[c-'a']++;
            if(c>='A'&&c<='Z')num[c-'A'+26]++;
        }
        int ans = 0;
        for(int i=0;i<26;i++){
            if(num[i]>0 && num[i+26]>0)ans++;
        }
        return ans;
    }
};

3121. 统计特殊字母的数量 II

给你一个字符串 word。如果 word 中同时出现某个字母 c 的小写形式和大写形式,并且 每个 小写形式的 c 都出现在第一个大写形式的 c 之前,则称字母 c 是一个 特殊字母 。

返回 word 中 特殊字母 的数量。

示例 1:

输入:word = "aaAbcBC"

输出:3

解释:

特殊字母是 'a''b' 和 'c'

示例 2:

输入:word = "abc"

输出:0

解释:

word 中不存在特殊字母。

示例 3:

输入:word = "AbBCab"

输出:0

解释:

word 中不存在特殊字母。

提示:

  • 1 <= word.length <= 2 * 105
  • word 仅由小写和大写英文字母组成。

class Solution {
public:
    int numberOfSpecialChars(string word) {
        int num[52];
        for(int i=0;i<52;i++)num[i]=0;
        for(auto c:word){
            if(c>='a'&&c<='z'){
                num[c-'a']++;
                if(num[c-'a'+26])num[c-'a']=-1234567;
            }
            if(c>='A'&&c<='Z')num[c-'A'+26]++;
        }
        int ans = 0;
        for(int i=0;i<26;i++){
            if(num[i]>0 && num[i+26]>0)ans++;
        }
        return ans;
    }
};

3127. 构造相同颜色的正方形

给你一个二维 3 x 3 的矩阵 grid ,每个格子都是一个字符,要么是 'B' ,要么是 'W' 。字符 'W' 表示白色,字符 'B' 表示黑色。

你的任务是改变 至多一个 格子的颜色,使得矩阵中存在一个 2 x 2 颜色完全相同的正方形。

如果可以得到一个相同颜色的 2 x 2 正方形,那么返回 true ,否则返回 false 。

示例 1:

输入:grid = [["B","W","B"],["B","W","W"],["B","W","B"]]

输出:true

解释:

修改 grid[0][2] 的颜色,可以满足要求。

示例 2:

输入:grid = [["B","W","B"],["W","B","W"],["B","W","B"]]

输出:false

解释:

只改变一个格子颜色无法满足要求。

示例 3:

输入:grid = [["B","W","B"],["B","W","W"],["B","W","W"]]

输出:true

解释:

grid 已经包含一个 2 x 2 颜色相同的正方形了。

提示:

  • grid.length == 3
  • grid[i].length == 3
  • grid[i][j] 要么是 'W' ,要么是 'B' 。
class Solution {
public:
    bool canMakeSquare(vector<vector<char>>& grid) {
        for(int i=1;i<grid.size();i++){
            for(int j=1;j<grid[0].size();j++){
                int s=0;
                if(grid[i][j]=='B')s++;
                if(grid[i][j-1]=='B')s++;
                if(grid[i-1][j]=='B')s++;
                if(grid[i-1][j-1]=='B')s++;
                if(s!=2)return true;
            }
        }
        return false;
    }
};

3131. 找出与数组相加的整数 I

给你两个长度相等的数组 nums1 和 nums2

数组 nums1 中的每个元素都与变量 x 所表示的整数相加。如果 x 为负数,则表现为元素值的减少。

在与 x 相加后,nums1 和 nums2 相等 。当两个数组中包含相同的整数,并且这些整数出现的频次相同时,两个数组 相等 。

返回整数 x 。

示例 1:

输入:nums1 = [2,6,4], nums2 = [9,7,5]

输出:3

解释:

与 3 相加后,nums1 和 nums2 相等。

示例 2:

输入:nums1 = [10], nums2 = [5]

输出:-5

解释:

与 -5 相加后,nums1 和 nums2 相等。

示例 3:

输入:nums1 = [1,1,1,1], nums2 = [1,1,1,1]

输出:0

解释:

与 0 相加后,nums1 和 nums2 相等。

提示:

  • 1 <= nums1.length == nums2.length <= 100
  • 0 <= nums1[i], nums2[i] <= 1000
  • 测试用例以这样的方式生成:存在一个整数 x,使得 nums1 中的每个元素都与 x 相加后,nums1 与 nums2 相等。
class Solution {
public:
    int addedInteger(vector<int>& nums1, vector<int>& nums2) {
        int m1=nums1[0],m2=nums2[0];
        for(auto x:nums1)m1=max(m1,x);
        for(auto x:nums2)m2=max(m2,x);
        return m2-m1;
    }
};

3132. 找出与数组相加的整数 II

双指针

3133. 数组最后一个元素的最小值

给你两个整数 n 和 x 。你需要构造一个长度为 n 的 正整数 数组 nums ,对于所有 0 <= i < n - 1 ,满足 nums[i + 1] 大于 nums[i] ,并且数组 nums 中所有元素的按位 AND 运算结果为 x 。

返回 nums[n - 1] 可能的 最小 值。

示例 1:

输入:n = 3, x = 4

输出:6

解释:

数组 nums 可以是 [4,5,6] ,最后一个元素为 6 。

示例 2:

输入:n = 2, x = 7

输出:15

解释:

数组 nums 可以是 [7,15] ,最后一个元素为 15 。

提示:

  • 1 <= n, x <= 108
class Solution {
public:
	long long minEnd(int n, int x) {
		long long s = x, one = 1;
		int m = n - 1;
		for (int i = 0; m; i++) {
			if (s&(one << i))continue;
			if (m & 1)s |= (one << i);
			m >>= 1;
		}
		return s;
	}
};

3142. 判断矩阵是否满足条件

给你一个大小为 m x n 的二维矩阵 grid 。你需要判断每一个格子 grid[i][j] 是否满足:

  • 如果它下面的格子存在,那么它需要等于它下面的格子,也就是 grid[i][j] == grid[i + 1][j] 。
  • 如果它右边的格子存在,那么它需要不等于它右边的格子,也就是 grid[i][j] != grid[i][j + 1] 。

如果 所有 格子都满足以上条件,那么返回 true ,否则返回 false 。

示例 1:

输入:grid = [[1,0,2],[1,0,2]]

输出:true

解释:

网格图中所有格子都符合条件。

示例 2:

输入:grid = [[1,1,1],[0,0,0]]

输出:false

解释:

示例 3:

输入:grid = [[1],[2],[3]]

输出:false

解释:

同一列中的格子值不相等。

提示:

  • 1 <= n, m <= 10
  • 0 <= grid[i][j] <= 9
class Solution {
public:
    bool satisfiesConditions(vector<vector<int>>& grid) {
        int r=grid.size(),c=grid[0].size();
        for(int i=0;i<r;i++){
            for(int j=1;j<c;j++)if(grid[i][j]==grid[i][j-1])return false;
        }
        for(int i=1;i<r;i++){
            for(int j=0;j<c;j++)if(grid[i][j]!=grid[i-1][j])return false;
        }
        return true;
    }
};

3143. 正方形中的最多点数

给你一个二维数组 points 和一个字符串 s ,其中 points[i] 表示第 i 个点的坐标,s[i] 表示第 i 个点的 标签 。

如果一个正方形的中心在 (0, 0) ,所有边都平行于坐标轴,且正方形内  存在标签相同的两个点,那么我们称这个正方形是 合法 的。

请你返回 合法 正方形中可以包含的 最多 点数。

注意:

  • 如果一个点位于正方形的边上或者在边以内,则认为该点位于正方形内。
  • 正方形的边长可以为零。

示例 1:

输入:points = [[2,2],[-1,-2],[-4,4],[-3,1],[3,-3]], s = "abdca"

输出:2

解释:

边长为 4 的正方形包含两个点 points[0] 和 points[1] 。

示例 2:

输入:points = [[1,1],[-2,-2],[-2,2]], s = "abb"

输出:1

解释:

边长为 2 的正方形包含 1 个点 points[0] 。

示例 3:

输入:points = [[1,1],[-1,-1],[2,-2]], s = "ccd"

输出:0

解释:

任何正方形都无法只包含 points[0] 和 points[1] 中的一个点,所以合法正方形中都不包含任何点。

提示:

  • 1 <= s.length, points.length <= 105
  • points[i].length == 2
  • -109 <= points[i][0], points[i][1] <= 109
  • s.length == points.length
  • points 中的点坐标互不相同。
  • s 只包含小写英文字母。
class Solution {
public:
    int maxPointsInsideSquare(vector<vector<int>>& points, string s) {
        vector<int>v,v2;
        for(auto vi:points)v.push_back(max(abs(vi[0]),abs(vi[1])));
        for(auto c:s)v2.push_back(c);
        SortExtend(v,v2);
        map<int,int>m;
        int maxSize = v[v.size()-1];
        for(int i=0;i<v.size();i++){
            if(m[v2[i]]){
                maxSize=v[i]-1;
                break;
            }
            m[v2[i]]=1;
        }
        int ans=0;
        for(auto x:v)if(x<=maxSize)ans++;
        return ans;
    }
};

3146. 两个字符串的排列差

给你两个字符串 s 和 t,每个字符串中的字符都不重复,且 t 是 s 的一个排列。

排列差 定义为 s 和 t 中每个字符在两个字符串中位置的绝对差值之和。

返回 s 和 t 之间的 排列差 

示例 1:

输入:s = "abc", t = "bac"

输出:2

解释:

对于 s = "abc" 和 t = "bac",排列差是:

  • "a" 在 s 中的位置与在 t 中的位置之差的绝对值。
  • "b" 在 s 中的位置与在 t 中的位置之差的绝对值。
  • "c" 在 s 中的位置与在 t 中的位置之差的绝对值。

即,s 和 t 的排列差等于 |0 - 1| + |1 - 0| + |2 - 2| = 2

示例 2:

输入:s = "abcde", t = "edbac"

输出:12

解释: s 和 t 的排列差等于 |0 - 3| + |1 - 2| + |2 - 4| + |3 - 1| + |4 - 0| = 12

提示:

  • 1 <= s.length <= 26
  • 每个字符在 s 中最多出现一次。
  • t 是 s 的一个排列。
  • s 仅由小写英文字母组成。
class Solution {
public:
    int findPermutationDifference(string s, string t) {
        map<char,int>m;
        int id=0,ans=0;
        for(auto c:s)m[c]=id++;
        for(int i=0;i<id;i++)ans+=abs(m[t[i]]-i);
        return ans;
    }
};

3151. 特殊数组 I

如果数组的每一对相邻元素都是两个奇偶性不同的数字,则该数组被认为是一个 特殊数组 。

你有一个整数数组 nums。如果 nums 是一个 特殊数组 ,返回 true,否则返回 false

示例 1:

输入:nums = [1]

输出:true

解释:

只有一个元素,所以答案为 true

示例 2:

输入:nums = [2,1,4]

输出:true

解释:

只有两对相邻元素: (2,1) 和 (1,4),它们都包含了奇偶性不同的数字,因此答案为 true

示例 3:

输入:nums = [4,3,1,6]

输出:false

解释:

nums[1] 和 nums[2] 都是奇数。因此答案为 false

提示:

  • 1 <= nums.length <= 100
  • 1 <= nums[i] <= 100
class Solution {
public:
    bool isArraySpecial(vector<int>& nums) {
        for(int i=1;i<nums.size();i++)if((nums[i]&1)==(nums[i-1]&1))return false;
        return true;
    }
};

3152. 特殊数组 II

如果数组的每一对相邻元素都是两个奇偶性不同的数字,则该数组被认为是一个 特殊数组 。

你有一个整数数组 nums 和一个二维整数矩阵 queries,对于 queries[i] = [fromi, toi],请你帮助你检查 

子数组

 nums[fromi..toi] 是不是一个 特殊数组 

返回布尔数组 answer,如果 nums[fromi..toi] 是特殊数组,则 answer[i] 为 true ,否则,answer[i] 为 false 。

示例 1:

输入:nums = [3,4,1,2,6], queries = [[0,4]]

输出:[false]

解释:

子数组是 [3,4,1,2,6]。2 和 6 都是偶数。

示例 2:

输入:nums = [4,3,1,6], queries = [[0,2],[2,3]]

输出:[false,true]

解释:

  1. 子数组是 [4,3,1]。3 和 1 都是奇数。因此这个查询的答案是 false
  2. 子数组是 [1,6]。只有一对:(1,6),且包含了奇偶性不同的数字。因此这个查询的答案是 true

提示:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 105
  • 1 <= queries.length <= 105
  • queries[i].length == 2
  • 0 <= queries[i][0] <= queries[i][1] <= nums.length - 1
class Solution {
public:
    vector<bool> isArraySpecial(vector<int>& nums, vector<vector<int>>& queries) {
        vector<int>id(nums.size());
        int low=0;
        for(int i=1;i<nums.size();i++){
            if((nums[i]&1)==(nums[i-1]&1)){
                for(int j=low;j<i;j++)id[j]=i;
                low=i;
            }
        }
        for(int j=low;j<nums.size();j++)id[j]=nums.size();
        vector<bool>ans;
        for(auto v:queries)ans.push_back(v[1]<id[v[0]]);
        return ans;
    }
};

3153. 所有数对中数位差之和

你有一个数组 nums ,它只包含  整数,所有正整数的数位长度都 相同 。

两个整数的 数位差 指的是两个整数 相同 位置上不同数字的数目。

请你返回 nums 中 所有 整数对里,数位差之和。

示例 1:

输入:nums = [13,23,12]

输出:4

解释:
计算过程如下:
13 和 23 的数位差为 1 。
- 13 和 12 的数位差为 1 。
23 和 12 的数位差为 2 。
所以所有整数数对的数位差之和为 1 + 1 + 2 = 4 。

示例 2:

输入:nums = [10,10,10,10]

输出:0

解释:
数组中所有整数都相同,所以所有整数数对的数位不同之和为 0 。

提示:

  • 2 <= nums.length <= 105
  • 1 <= nums[i] < 109
  • nums 中的整数都有相同的数位长度。
class Solution {
public:
    long long sumDigitDifferences(vector<int>& nums) {
        vector<int>v(10);
        long long ans=0;
        while(nums[0]){
            for(int i=0;i<10;i++)v[i]=0;
            for(auto &x:nums)v[x%10]++,x/=10;
            ans+=sumOneBit(v,nums.size());
        }
        return ans;
    }
    long long sumOneBit(vector<int>v,long long s)
    {
        long long ans=0;
        for(auto x:v)ans+=x*(s-x);
        return ans/2;
    }
};

3159. 查询数组中元素的出现位置

给你一个整数数组 nums ,一个整数数组 queries 和一个整数 x 。

对于每个查询 queries[i] ,你需要找到 nums 中第 queries[i] 个 x 的位置,并返回它的下标。如果数组中 x 的出现次数少于 queries[i] ,该查询的答案为 -1 。

请你返回一个整数数组 answer ,包含所有查询的答案。

示例 1:

输入:nums = [1,3,1,7], queries = [1,3,2,4], x = 1

输出:[0,-1,2,-1]

解释:

  • 第 1 个查询,第一个 1 出现在下标 0 处。
  • 第 2 个查询,nums 中只有两个 1 ,所以答案为 -1 。
  • 第 3 个查询,第二个 1 出现在下标 2 处。
  • 第 4 个查询,nums 中只有两个 1 ,所以答案为 -1 。

示例 2:

输入:nums = [1,2,3], queries = [10], x = 5

输出:[-1]

解释:

  • 第 1 个查询,nums 中没有 5 ,所以答案为 -1 。

提示:

  • 1 <= nums.length, queries.length <= 105
  • 1 <= queries[i] <= 105
  • 1 <= nums[i], x <= 104
class Solution {
public:
	vector<int> occurrencesOfElement(vector<int>& nums, vector<int>& queries, int x) {
		map<int, vector<int>>m;
		for (int i = 0; i < nums.size(); i++) {
			m[nums[i]].push_back(i);
		}
		auto v = m[x];
		vector<int>ans;
		for (auto q : queries) {
			if (q > v.size())ans.push_back(-1);
			else ans.push_back(v[q-1]);
		}
		return ans;
	}
};

3162. 优质数对的总数 I

给你两个整数数组 nums1 和 nums2,长度分别为 n 和 m。同时给你一个正整数 k

如果 nums1[i] 可以除尽 nums2[j] * k,则称数对 (i, j) 为 优质数对0 <= i <= n - 10 <= j <= m - 1)。

返回 优质数对 的总数。

示例 1:

输入:nums1 = [1,3,4], nums2 = [1,3,4], k = 1

输出:5

解释:

5个优质数对分别是 (0, 0)(1, 0)(1, 1)(2, 0), 和 (2, 2)

示例 2:

输入:nums1 = [1,2,4,12], nums2 = [2,4], k = 3

输出:2

解释:

2个优质数对分别是 (3, 0) 和 (3, 1)

提示:

  • 1 <= n, m <= 50
  • 1 <= nums1[i], nums2[j] <= 50
  • 1 <= k <= 50
class Solution {
public:
    int numberOfPairs(vector<int>& nums1, vector<int>& nums2, int k) {
        int ans=0;
        for(auto x:nums1){
            for(auto y:nums2){
                if(x/y/k*k*y==x)ans++;
            }
        }
        return ans;
    }
};

3176. 求出最长好子序列 I

给你一个整数数组 nums 和一个 非负 整数 k 。如果一个整数序列 seq 满足在下标范围 [0, seq.length - 2] 中 最多只有 k 个下标 i 满足 seq[i] != seq[i + 1] ,那么我们称这个整数序列为  序列。

请你返回 nums 中  

子序列

 的最长长度。

示例 1:

输入:nums = [1,2,1,1,3], k = 2

输出:4

解释:

最长好子序列为 [1,2,1,1,3] 。

示例 2:

输入:nums = [1,2,3,4,5,1], k = 0

输出:2

解释:

最长好子序列为 [1,2,3,4,5,1] 。

提示:

  • 1 <= nums.length <= 500
  • 1 <= nums[i] <= 109
  • 0 <= k <= min(nums.length, 25)
class Solution {
public:
	int maximumLength(vector<int>& nums, int k) {
		map<int, map<int, int>>m;
		map<int, int>id;
		map<int, int>ans;
		for (int i = 0; i < nums.size(); i++) {
			bool flag = (id.find(nums[i]) != id.end());
			for (int j = 0; j <= k; j++) {
				m[i][j] = max(m[i][j], (j ? ans[j - 1] : 0) + 1);
				if (flag)m[i][j] = max(m[i][j], m[id[nums[i]]][j] + 1);
			}
			for (int j = 0; j <= k; j++) {
				ans[j] = max(ans[j], m[i][j]);
			}
			id[nums[i]] = i;
		}
		int r = 0;
		for (auto mi : ans)r = max(r, mi.second);
		return r;
	}
};

3177. 求出最长好子序列 II

给你一个整数数组 nums 和一个 非负 整数 k 。如果一个整数序列 seq 满足在范围下标范围 [0, seq.length - 2] 中存在 不超过 k 个下标 i 满足 seq[i] != seq[i + 1] ,那么我们称这个整数序列为  序列。

请你返回 nums 中  子序列 的最长长度

示例 1:

输入:nums = [1,2,1,1,3], k = 2

输出:4

解释:

最长好子序列为 [1,2,1,1,3] 。

示例 2:

输入:nums = [1,2,3,4,5,1], k = 0

输出:2

解释:

最长好子序列为 [1,2,3,4,5,1] 。

提示:

  • 1 <= nums.length <= 5 * 103
  • 1 <= nums[i] <= 109
  • 0 <= k <= min(50, nums.length)
class Solution {
public:
	int maximumLength(vector<int>& nums, int k) {
		unordered_map<int, unordered_map<int, int>>m;
		map<int, int>id;
		map<int, int>ans;
		for (int i = 0; i < nums.size(); i++) {
			bool flag = (id.find(nums[i]) != id.end());
			for (int j = 0; j <= k; j++) {
				m[i][j] = max(m[i][j], (j ? ans[j - 1] : 0) + 1);
				if (flag)m[i][j] = max(m[i][j], m[id[nums[i]]][j] + 1);
			}
			for (int j = 0; j <= k; j++) {
				ans[j] = max(ans[j], m[i][j]);
			}
			id[nums[i]] = i;
		}
		int r = 0;
		for (auto mi : ans)r = max(r, mi.second);
		return r;
	}
};

3180. 执行操作可获得的最大总奖励 I

给你一个整数数组 rewardValues,长度为 n,代表奖励的值。

最初,你的总奖励 x 为 0,所有下标都是 未标记 的。你可以执行以下操作 任意次 

  • 从区间 [0, n - 1] 中选择一个 未标记 的下标 i
  • 如果 rewardValues[i] 大于 你当前的总奖励 x,则将 rewardValues[i] 加到 x 上(即 x = x + rewardValues[i]),并 标记 下标 i

以整数形式返回执行最优操作能够获得的 最大 总奖励。

示例 1:

输入:rewardValues = [1,1,3,3]

输出:4

解释:

依次标记下标 0 和 2,总奖励为 4,这是可获得的最大值。

示例 2:

输入:rewardValues = [1,6,4,3,2]

输出:11

解释:

依次标记下标 0、2 和 1。总奖励为 11,这是可获得的最大值。

提示:

  • 1 <= rewardValues.length <= 2000
  • 1 <= rewardValues[i] <= 2000
class Solution {
public:
	int maxTotalReward(vector<int>& v) {
		sort(v.begin(), v.end());
		set<int>s1, s2;
		s2.insert(0);
		for (auto x : v) {
			s1 = s2;
			for (auto y : s1) {
				if (y >= x)break;
				s2.insert(y + x);
			}
		}
		return *s2.rbegin();
	}
};

3185. 构成整天的下标对数目 II

给你一个整数数组 hours,表示以 小时 为单位的时间,返回一个整数,表示满足 i < j 且 hours[i] + hours[j] 构成 整天 的下标对 ij 的数目。

整天 定义为时间持续时间是 24 小时的 整数倍 

例如,1 天是 24 小时,2 天是 48 小时,3 天是 72 小时,以此类推。

示例 1:

输入: hours = [12,12,30,24,24]

输出: 2

解释:

构成整天的下标对分别是 (0, 1) 和 (3, 4)

示例 2:

输入: hours = [72,48,24,3]

输出: 3

解释:

构成整天的下标对分别是 (0, 1)(0, 2) 和 (1, 2)

提示:

  • 1 <= hours.length <= 5 * 105
  • 1 <= hours[i] <= 109
class Solution {
public:
    long long countCompleteDayPairs(vector<int>& hours) {
        map<int,long long>m;
        for(auto x:hours)m[x%24]++;
        long long ans=m[0]*(m[0]-1)/2+m[12]*(m[12]-1)/2;
        for(int i=1;i<12;i++)ans+=m[i]*m[24-i];
        return ans;
    }
};

3191. 使二进制数组全部等于 1 的最少操作次数 I

给你一个二进制数组 nums 。

你可以对数组执行以下操作 任意 次(也可以 0 次):

  • 选择数组中 任意连续 3 个元素,并将它们 全部反转 。

反转 一个元素指的是将它的值从 0 变 1 ,或者从 1 变 0 。

请你返回将 nums 中所有元素变为 1 的 最少 操作次数。如果无法全部变成 1 ,返回 -1 。

示例 1:

输入:nums = [0,1,1,1,0,0]

输出:3

解释:
我们可以执行以下操作:

  • 选择下标为 0 ,1 和 2 的元素并反转,得到 nums = [1,0,0,1,0,0] 。
  • 选择下标为 1 ,2 和 3 的元素并反转,得到 nums = [1,1,1,0,0,0] 。
  • 选择下标为 3 ,4 和 5 的元素并反转,得到 nums = [1,1,1,1,1,1] 。

示例 2:

输入:nums = [0,1,1,1]

输出:-1

解释:
无法将所有元素都变为 1 。

提示:

  • 3 <= nums.length <= 105
  • 0 <= nums[i] <= 1
class Solution {
public:
    int minOperations(vector<int>& nums) {
        int ans=0;
        for(int i=0;i<nums.size()-2;i++){
            if(nums[i]==0)nums[i]^=1,nums[i+1]^=1,nums[i+2]^=1,ans++;
        }
        return (nums[nums.size()-1] & nums[nums.size()-2]) ?ans : -1;
    }
};

3192. 使二进制数组全部等于 1 的最少操作次数 II

给你一个二进制数组 nums 。

你可以对数组执行以下操作 任意 次(也可以 0 次):

  • 选择数组中 任意 一个下标 i ,并将从下标 i 开始一直到数组末尾 所有 元素 反转 。

反转 一个元素指的是将它的值从 0 变 1 ,或者从 1 变 0 。

请你返回将 nums 中所有元素变为 1 的 最少 操作次数。

示例 1:

输入:nums = [0,1,1,0,1]

输出:4

解释:
我们可以执行以下操作:

  • 选择下标 i = 1 执行操作,得到 nums = [0,0,0,1,0] 。
  • 选择下标 i = 0 执行操作,得到 nums = [1,1,1,0,1] 。
  • 选择下标 i = 4 执行操作,得到 nums = [1,1,1,0,0] 。
  • 选择下标 i = 3 执行操作,得到 nums = [1,1,1,1,1] 。

示例 2:

输入:nums = [1,0,0,0]

输出:1

解释:
我们可以执行以下操作:

  • 选择下标 i = 1 执行操作,得到 nums = [1,1,1,1] 。

提示:

  • 1 <= nums.length <= 105
  • 0 <= nums[i] <= 1
class Solution {
public:
	int minOperations(vector<int>& nums) {
		int a = 1, ans = 0;
		for (auto x : nums) {
			if (x != a)ans++;
			a = x;
		}
		return ans;
	}
};

3195. 包含所有 1 的最小矩形面积 I

给你一个二维 二进制 数组 grid。请你找出一个边在水平方向和竖直方向上、面积 最小 的矩形,并且满足 grid 中所有的 1 都在矩形的内部。

返回这个矩形可能的 最小 面积。

示例 1:

输入: grid = [[0,1,0],[1,0,1]]

输出: 6

解释:

这个最小矩形的高度为 2,宽度为 3,因此面积为 2 * 3 = 6

示例 2:

输入: grid = [[0,0],[1,0]]

输出: 1

解释:

这个最小矩形的高度和宽度都是 1,因此面积为 1 * 1 = 1

提示:

  • 1 <= grid.length, grid[i].length <= 1000
  • grid[i][j] 是 0 或 1。
  • 输入保证 grid 中至少有一个 1 。
class Solution {
public:
	int minimumArea(vector<vector<int>>& grid) {
		int r = grid.size(), c = grid[0].size();
		int x1 = r, x2 = 0, y1 = c, y2 = 0;
		for (int i = 0; i < r; i++) {
			for (int j = 0; j < c; j++) {
				if (grid[i][j])x1 = min(x1, i), x2 = max(x2, i), y1 = min(y1, j), y2 = max(y2, j);
			}
		}
		return (x2 - x1 + 1)*(y2 - y1 + 1);
	}
};

3206. 交替组 I

给你一个整数数组 colors ,它表示一个由红色和蓝色瓷砖组成的环,第 i 块瓷砖的颜色为 colors[i] :

  • colors[i] == 0 表示第 i 块瓷砖的颜色是 红色 。
  • colors[i] == 1 表示第 i 块瓷砖的颜色是 蓝色 。

环中连续 3 块瓷砖的颜色如果是 交替 颜色(也就是说中间瓷砖的颜色与它 左边 和 右边 的颜色都不同),那么它被称为一个 交替 组。

请你返回 交替 组的数目。

注意 ,由于 colors 表示一个  ,第一块 瓷砖和 最后一块 瓷砖是相邻的。

示例 1:

输入:colors = [1,1,1]

输出:0

解释:

示例 2:

输入:colors = [0,1,0,0,1]

输出:3

解释:

交替组包括:

提示:

  • 3 <= colors.length <= 100
  • 0 <= colors[i] <= 1
class Solution {
public:
	int numberOfAlternatingGroups(vector<int>& colors) {
		int n = colors.size(), ans = 0;
		for (int i = 0; i < n; i++) {
			if (colors[i] != colors[(i + 1) % n] && colors[i] != colors[(i - 1 + n) % n])ans++;
		}
		return ans;
	}
};

3208. 交替组 II

给你一个整数数组 colors 和一个整数 k ,colors表示一个由红色和蓝色瓷砖组成的环,第 i 块瓷砖的颜色为 colors[i] :

  • colors[i] == 0 表示第 i 块瓷砖的颜色是 红色 。
  • colors[i] == 1 表示第 i 块瓷砖的颜色是 蓝色 。

环中连续 k 块瓷砖的颜色如果是 交替 颜色(也就是说除了第一块和最后一块瓷砖以外,中间瓷砖的颜色与它 左边 和 右边 的颜色都不同),那么它被称为一个 交替 组。

请你返回 交替 组的数目。

注意 ,由于 colors 表示一个  ,第一块 瓷砖和 最后一块 瓷砖是相邻的。

示例 1:

输入:colors = [0,1,0,1,0], k = 3

输出:3

解释:

交替组包括:

示例 2:

输入:colors = [0,1,0,0,1,0,1], k = 6

输出:2

解释:

交替组包括:

示例 3:

输入:colors = [1,1,0,1], k = 4

输出:0

解释:

提示:

  • 3 <= colors.length <= 105
  • 0 <= colors[i] <= 1
  • 3 <= k <= colors.length
class Solution {
public:
	int numberOfAlternatingGroups(vector<int>& v, int k) {
		int n = v.size();
		for (int i = 0; i < k-1; i++)v.push_back(v[i]);
		int s = 0, ans = 0;
		for (int i = 1; i < v.size(); i++) {
			if (v[i] != v[i - 1])s++;
			if (i >= k && v[i - k + 1] != v[i - k])s--;
			if (s == k - 1)ans++;
		}
		return ans;
	}
};

3211. 生成不含相邻零的二进制字符串

给你一个正整数 n

如果一个二进制字符串 x 的所有长度为 2 的

子字符串

中包含 至少 一个 "1",则称 x 是一个 有效 字符串。

返回所有长度为 n 的 有效 字符串,可以以任意顺序排列。

示例 1:

输入: n = 3

输出: ["010","011","101","110","111"]

解释:

长度为 3 的有效字符串有:"010""011""101""110" 和 "111"

示例 2:

输入: n = 1

输出: ["0","1"]

解释:

长度为 1 的有效字符串有:"0" 和 "1"

提示:

  • 1 <= n <= 18
class Solution {
public:
    vector<string> validStrings(int n) {
        if(n==1)return vector<string>{"0","1"};
        auto v=validStrings(n-1);
        vector<string> ans;
        for(auto s:v){
            if(s[n-2]=='1')ans.push_back(s+"0");
            ans.push_back(s+"1");
        }
        return ans;
    }
};

3216. 交换后字典序最小的字符串

给你一个仅由数字组成的字符串 s,在最多交换一次 相邻 且具有相同 奇偶性 的数字后,返回可以得到的

字典序最小的字符串

如果两个数字都是奇数或都是偶数,则它们具有相同的奇偶性。例如,5 和 9、2 和 4 奇偶性相同,而 6 和 9 奇偶性不同。

示例 1:

输入: s = "45320"

输出: "43520"

解释:

s[1] == '5' 和 s[2] == '3' 都具有相同的奇偶性,交换它们可以得到字典序最小的字符串。

示例 2:

输入: s = "001"

输出: "001"

解释:

无需进行交换,因为 s 已经是字典序最小的。

提示:

  • 2 <= s.length <= 100
  • s 仅由数字组成。
class Solution {
public:
    string getSmallestString(string s) {
        for(int i=0;i<s.length()-1;i++){
            if((s[i]-s[i+1])%2==0 && s[i]>s[i+1]){
                char c=s[i];
                s[i]=s[i+1],s[i+1]=c;
                return s;
            }
        }
        return s;
    }
};

3217. 从链表中移除在数组中存在的节点

给你一个整数数组 nums 和一个链表的头节点 head。从链表中移除所有存在于 nums 中的节点后,返回修改后的链表的头节点。

示例 1:

输入: nums = [1,2,3], head = [1,2,3,4,5]

输出: [4,5]

解释:

移除数值为 1, 2 和 3 的节点。

示例 2:

输入: nums = [1], head = [1,2,1,2,1,2]

输出: [2,2,2]

解释:

移除数值为 1 的节点。

示例 3:

输入: nums = [5], head = [1,2,3,4]

输出: [1,2,3,4]

解释:

链表中不存在值为 5 的节点。

提示:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 105
  • nums 中的所有元素都是唯一的。
  • 链表中的节点数在 [1, 105] 的范围内。
  • 1 <= Node.val <= 105
  • 输入保证链表中至少有一个值没有在 nums 中出现过。
class Solution {
public:
    ListNode* modifiedList(vector<int>& nums, ListNode* head) {
        auto v=ListToVec(head);
        map<int,int>m;
        for(auto x:nums)m[x]++;
        vector<ListNode*>v2;
        for(auto x:v)if(m[x->val]==0)v2.push_back(x);
        return VecToList(v2);
    }
};

3218. 切蛋糕的最小总开销 I

3219. 切蛋糕的最小总开销 II的简化版

3219. 切蛋糕的最小总开销 II

贪心

3222. 求出硬币游戏的赢家

给你两个  整数 x 和 y ,分别表示价值为 75 和 10 的硬币的数目。

Alice 和 Bob 正在玩一个游戏。每一轮中,Alice 先进行操作,Bob 后操作。每次操作中,玩家需要拿走价值 总和 为 115 的硬币。如果一名玩家无法执行此操作,那么这名玩家 输掉 游戏。

两名玩家都采取 最优 策略,请你返回游戏的赢家。

示例 1:

输入:x = 2, y = 7

输出:"Alice"

解释:

游戏一次操作后结束:

  • Alice 拿走 1 枚价值为 75 的硬币和 4 枚价值为 10 的硬币。

示例 2:

输入:x = 4, y = 11

输出:"Bob"

解释:

游戏 2 次操作后结束:

  • Alice 拿走 1 枚价值为 75 的硬币和 4 枚价值为 10 的硬币。
  • Bob 拿走 1 枚价值为 75 的硬币和 4 枚价值为 10 的硬币。

提示:

  • 1 <= x, y <= 100
class Solution {
public:
    string losingPlayer(int x, int y) {
        return min(x,y/4)%2?"Alice":"Bob";
    }
};

3226. 使两个整数相等的位更改次数

给你两个正整数 n 和 k

你可以选择 n 的 二进制表示 中任意一个值为 1 的位,并将其改为 0。

返回使得 n 等于 k 所需要的更改次数。如果无法实现,返回 -1。

示例 1:

输入: n = 13, k = 4

输出: 2

解释:
最初,n 和 k 的二进制表示分别为 n = (1101)2 和 k = (0100)2

我们可以改变 n 的第一位和第四位。结果整数为 n = (0100)2 = k

示例 2:

输入: n = 21, k = 21

输出: 0

解释:
n 和 k 已经相等,因此不需要更改。

示例 3:

输入: n = 14, k = 13

输出: -1

解释:
无法使 n 等于 k

提示:

  • 1 <= n, k <= 106
class Solution {
public:
    int minChanges(int n, int k) {
        if((n&k)!=k)return -1;
        n^=k;
        int ans=0;
        while(n){
            n^=(n&-n);
            ans++;
        }
        return ans;
    }
};

3232. 判断是否可以赢得数字游戏

给你一个 正整数 数组 nums

Alice 和 Bob 正在玩游戏。在游戏中,Alice 可以从 nums 中选择所有个位数  所有两位数,剩余的数字归 Bob 所有。如果 Alice 所选数字之和 严格大于 Bob 的数字之和,则 Alice 获胜。

如果 Alice 能赢得这场游戏,返回 true;否则,返回 false

示例 1:

输入:nums = [1,2,3,4,10]

输出:false

解释:

Alice 不管选个位数还是两位数都无法赢得比赛。

示例 2:

输入:nums = [1,2,3,4,5,14]

输出:true

解释:

Alice 选择个位数可以赢得比赛,所选数字之和为 15。

示例 3:

输入:nums = [5,5,5,25]

输出:true

解释:

Alice 选择两位数可以赢得比赛,所选数字之和为 25。

提示:

  • 1 <= nums.length <= 100
  • 1 <= nums[i] <= 99
class Solution {
public:
	bool canAliceWin(vector<int>& nums) {
		int s1 = 0, s2 = 0;
		for (auto x : nums) {
			if (x < 10)s1 += x;
			else s2 += x;
		}
		return s1 != s2;
	}
};

3238. 求出胜利玩家的数目

给你一个整数 n ,表示在一个游戏中的玩家数目。同时给你一个二维整数数组 pick ,其中 pick[i] = [xi, yi] 表示玩家 xi 获得了一个颜色为 yi 的球。

如果玩家 i 获得的球中任何一种颜色球的数目 严格大于 i 个,那么我们说玩家 i 是胜利玩家。换句话说:

  • 如果玩家 0 获得了任何的球,那么玩家 0 是胜利玩家。
  • 如果玩家 1 获得了至少 2 个相同颜色的球,那么玩家 1 是胜利玩家。
  • ...
  • 如果玩家 i 获得了至少 i + 1 个相同颜色的球,那么玩家 i 是胜利玩家。

请你返回游戏中 胜利玩家 的数目。

注意,可能有多个玩家是胜利玩家。

示例 1:

输入:n = 4, pick = [[0,0],[1,0],[1,0],[2,1],[2,1],[2,0]]

输出:2

解释:

玩家 0 和玩家 1 是胜利玩家,玩家 2 和玩家 3 不是胜利玩家。

示例 2:

输入:n = 5, pick = [[1,1],[1,2],[1,3],[1,4]]

输出:0

解释:

没有胜利玩家。

示例 3:

输入:n = 5, pick = [[1,1],[2,4],[2,4],[2,4]]

输出:1

解释:

玩家 2 是胜利玩家,因为玩家 2 获得了 3 个颜色为 4 的球。

提示:

  • 2 <= n <= 10
  • 1 <= pick.length <= 100
  • pick[i].length == 2
  • 0 <= xi <= n - 1
  • 0 <= yi <= 10
class Solution {
public:
	int winningPlayerCount(int n, vector<vector<int>>& pick) {
		vector<map<int, int>>vm(n);
		for (auto v : pick)vm[v[0]][v[1]]++;
		int ans = 0;
		for (int i = 0; i < n; i++) {
			for (auto mi : vm[i])if (mi.second > i) {
				ans++;
				break;
			}
		}
		return ans;
	}
};

3239. 最少翻转次数使二进制矩阵回文 I

给你一个 m x n 的二进制矩阵 grid 。

如果矩阵中一行或者一列从前往后与从后往前读是一样的,那么我们称这一行或者这一列是 回文 的。

你可以将 grid 中任意格子的值 翻转 ,也就是将格子里的值从 0 变成 1 ,或者从 1 变成 0 。

请你返回 最少 翻转次数,使得矩阵 要么 所有行是 回文的 ,要么所有列是 回文的 。

示例 1:

输入:grid = [[1,0,0],[0,0,0],[0,0,1]]

输出:2

解释:

将高亮的格子翻转,得到所有行都是回文的。

示例 2:

输入:grid = [[0,1],[0,1],[0,0]]

输出:1

解释:

将高亮的格子翻转,得到所有列都是回文的。

示例 3:

输入:grid = [[1],[0]]

输出:0

解释:

所有行已经是回文的。

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m * n <= 2 * 105
  • 0 <= grid[i][j] <= 1
class Solution {
public:
	int minFlips(vector<vector<int>>& grid) {
		int ans1 = 0, ans2 = 0;
		for (auto v : grid)ans1 += minFlips(v);
		for (int i = 0; i < grid[0].size(); i++) {
			vector<int>v;
			for (int j = 0; j < grid.size(); j++)v.push_back(grid[j][i]);
			ans2 += minFlips(v);
		}
		return min(ans1, ans2);
	}
	int minFlips(vector<int>&v)
	{
		int s = 0;
		for (int i = 0, j = v.size() - 1; i < j; i++, j--) {
			s += (v[i] + v[j]) % 2;
		}
		return s;
	}
};

3240. 最少翻转次数使二进制矩阵回文 II

给你一个 m x n 的二进制矩阵 grid 。

如果矩阵中一行或者一列从前往后与从后往前读是一样的,那么我们称这一行或者这一列是 回文 的。

你可以将 grid 中任意格子的值 翻转 ,也就是将格子里的值从 0 变成 1 ,或者从 1 变成 0 。

请你返回 最少 翻转次数,使得矩阵中 所有 行和列都是 回文的 ,且矩阵中 1 的数目可以被 4 整除 。

示例 1:

输入:grid = [[1,0,0],[0,1,0],[0,0,1]]

输出:3

解释:

示例 2:

输入:grid = [[0,1],[0,1],[0,0]]

输出:2

解释:

示例 3:

输入:grid = [[1],[1]]

输出:2

解释:

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m * n <= 2 * 105
  • 0 <= grid[i][j] <= 1
class Solution {
public:
	int minFlips(vector<vector<int>>& grid) {
		int ans = 0, r = grid.size(), c = grid[0].size();
		for (int i = 0; i < r / 2; i++) {
			for (int j = 0; j < c / 2; j++) {
				int s = grid[i][j] + grid[i][c - 1 - j] + grid[r - 1 - i][j] + grid[r - 1 - i][c - 1 - j];
				if (s == 1 || s == 3)ans++;
				if (s == 2)ans += 2;
			}
		}
		if (r % 2 == 1 && c % 2 == 1)ans += grid[r / 2][c / 2];
		int n01 = 0, n11 = 0;
		if (r % 2 == 1) {
			for (int j = 0; j < c / 2; j++) {
				n01 += (grid[r / 2][j] ^ grid[r / 2][c - 1 - j]);
				n11 += grid[r / 2][j] * grid[r / 2][c - 1 - j];
			}
		}
		if (c % 2 == 1) {
			for (int i = 0; i < r / 2; i++) {
				n01 += (grid[i][c / 2] ^ grid[r - 1 - i][c / 2]);
				n11 += grid[i][c / 2] * grid[r - 1 - i][c / 2];
			}
		}
		ans += n01 ? n01 : (n11 % 2 * 2);
		return ans;
	}
};

3242. 设计相邻元素求和服务

给你一个 n x n 的二维数组 grid,它包含范围 [0, n2 - 1] 内的不重复元素。

实现 neighborSum 类:

  • neighborSum(int [][]grid) 初始化对象。
  • int adjacentSum(int value) 返回在 grid 中与 value 相邻的元素之,相邻指的是与 value 在上、左、右或下的元素。
  • int diagonalSum(int value) 返回在 grid 中与 value 对角线相邻的元素之,对角线相邻指的是与 value 在左上、右上、左下或右下的元素。

示例 1:

输入:

["neighborSum", "adjacentSum", "adjacentSum", "diagonalSum", "diagonalSum"]

[[[[0, 1, 2], [3, 4, 5], [6, 7, 8]]], [1], [4], [4], [8]]

输出: [null, 6, 16, 16, 4]

解释:

  • 1 的相邻元素是 0、2 和 4。
  • 4 的相邻元素是 1、3、5 和 7。
  • 4 的对角线相邻元素是 0、2、6 和 8。
  • 8 的对角线相邻元素是 4。

示例 2:

输入:

["neighborSum", "adjacentSum", "diagonalSum"]

[[[[1, 2, 0, 3], [4, 7, 15, 6], [8, 9, 10, 11], [12, 13, 14, 5]]], [15], [9]]

输出: [null, 23, 45]

解释:

  • 15 的相邻元素是 0、10、7 和 6。
  • 9 的对角线相邻元素是 4、12、14 和 15。

提示:

  • 3 <= n == grid.length == grid[0].length <= 10
  • 0 <= grid[i][j] <= n2 - 1
  • 所有 grid[i][j] 值均不重复。
  • adjacentSum 和 diagonalSum 中的 value 均在范围 [0, n2 - 1] 内。
  • 最多会调用 adjacentSum 和 diagonalSum 总共 2 * n2 次。
class NeighborSum {
public:
    NeighborSum(vector<vector<int>>& grid) {
        this->grid = grid;
    }
    
    int adjacentSum(int value) {
        int i=0,j=0,flag=true;
        for(i=0;flag && i<grid.size();i++){
            for(j=0;j<grid[i].size();j++){
                if(grid[i][j]==value){
                    flag=false;
                    break;
                }
            }
        }
        int ans=0;
        if(--i)ans+=grid[i-1][j];
        if(i<grid.size()-1)ans+=grid[i+1][j];
        if(j)ans+=grid[i][j-1];
        if(j<grid[i].size()-1)ans+=grid[i][j+1];
        return ans;
    }
    
    int diagonalSum(int value) {
        int i=0,j=0,flag=true;
        for(i=0;flag && i<grid.size();i++){
            for(j=0;j<grid[i].size();j++){
                if(grid[i][j]==value){
                    flag=false;
                    break;
                }
            }
        }
        int ans=0;
        if(--i>0&&j>0)ans+=grid[i-1][j-1];
        if(i>0&&j<grid[i].size()-1)ans+=grid[i-1][j+1];
        if(i<grid.size()-1&&j>0)ans+=grid[i+1][j-1];
        if(i<grid.size()-1&&j<grid[i].size()-1)ans+=grid[i+1][j+1];
        return ans;
    }
    vector<vector<int>> grid;
};

3248. 矩阵中的蛇

大小为 n x n 的矩阵 grid 中有一条蛇。蛇可以朝 四个可能的方向 移动。矩阵中的每个单元格都使用位置进行标识: grid[i][j] = (i * n) + j

蛇从单元格 0 开始,并遵循一系列命令移动。

给你一个整数 n 表示 grid 的大小,另给你一个字符串数组 commands,其中包括 "UP""RIGHT""DOWN" 和 "LEFT"。题目测评数据保证蛇在整个移动过程中将始终位于 grid 边界内。

返回执行 commands 后蛇所停留的最终单元格的位置。

示例 1:

输入:n = 2, commands = ["RIGHT","DOWN"]

输出:3

解释:

01
23
01
23
01
23

示例 2:

输入:n = 3, commands = ["DOWN","RIGHT","UP"]

输出:1

解释:

012
345
678
012
345
678
012
345
678
012
345
678

提示:

  • 2 <= n <= 10
  • 1 <= commands.length <= 100
  • commands 仅由 "UP""RIGHT""DOWN" 和 "LEFT" 组成。
  • 生成的测评数据确保蛇不会移动到矩阵的边界外。
class Solution {
public:
	int finalPositionOfSnake(int n, vector<string>& commands) {
		int x = 0, y = 0;
		for (auto s : commands) {
			if (s == "UP")x--;
			if (s == "DOWN")x++;
			if (s == "LEFT")y--;
			if (s == "RIGHT")y++;
		}
		return x * n + y;
	}
};

3249. 统计好节点的数目

多叉树

3250. 单调数组对的数目 I

给你一个长度为 n 的  整数数组 nums 。

如果两个 非负 整数数组 (arr1, arr2) 满足以下条件,我们称它们是 单调 数组对:

  • 两个数组的长度都是 n 。
  • arr1 是单调 非递减 的,换句话说 arr1[0] <= arr1[1] <= ... <= arr1[n - 1] 。
  • arr2 是单调 非递增 的,换句话说 arr2[0] >= arr2[1] >= ... >= arr2[n - 1] 。
  • 对于所有的 0 <= i <= n - 1 都有 arr1[i] + arr2[i] == nums[i] 。

请你返回所有 单调 数组对的数目。

由于答案可能很大,请你将它对 109 + 7 取余 后返回。

示例 1:

输入:nums = [2,3,2]

输出:4

解释:

单调数组对包括:

  1. ([0, 1, 1], [2, 2, 1])
  2. ([0, 1, 2], [2, 2, 0])
  3. ([0, 2, 2], [2, 1, 0])
  4. ([1, 2, 2], [1, 1, 0])

示例 2:

输入:nums = [5,5,5,5]

输出:126

提示:

  • 1 <= n == nums.length <= 2000
  • 1 <= nums[i] <= 50

本题同3251. 单调数组对的数目 II,只是数据量小一点。

3251. 单调数组对的数目 II

给你一个长度为 n 的  整数数组 nums 。

如果两个 非负 整数数组 (arr1, arr2) 满足以下条件,我们称它们是 单调 数组对:

  • 两个数组的长度都是 n 。
  • arr1 是单调 非递减 的,换句话说 arr1[0] <= arr1[1] <= ... <= arr1[n - 1] 。
  • arr2 是单调 非递增 的,换句话说 arr2[0] >= arr2[1] >= ... >= arr2[n - 1] 。
  • 对于所有的 0 <= i <= n - 1 都有 arr1[i] + arr2[i] == nums[i] 。

请你返回所有 单调 数组对的数目。

由于答案可能很大,请你将它对 109 + 7 取余 后返回。

示例 1:

输入:nums = [2,3,2]

输出:4

解释:

单调数组对包括:

  1. ([0, 1, 1], [2, 2, 1])
  2. ([0, 1, 2], [2, 2, 0])
  3. ([0, 2, 2], [2, 1, 0])
  4. ([1, 2, 2], [1, 1, 0])

示例 2:

输入:nums = [5,5,5,5]

输出:126

提示:

  • 1 <= n == nums.length <= 2000
  • 1 <= nums[i] <= 1000
class Solution {
public:
	int countOfPairs(vector<int>& nums) {
		int p = 1000000007;
		vector<long long>ans(1001, 0);
		for (int i = 0; i <= nums[0]; i++)ans[i] = 1;
		for (int i = 1; i < nums.size(); i++) {
			for (int i = 1; i <= 1000; i++)ans[i] = (ans[i] + ans[i - 1]) % p;
			vector<long long>s(1001, 0);
			for (int j = 0; j <= nums[i]; j++) {
				auto maxid = min(nums[i - 1], min(j, j + nums[i - 1] - nums[i]));
				if (maxid >= 0)s[j] = ans[maxid];
			}
			ans = s;
		}
		long long r = 0;
		for (int i = 0; i <= 1000; i++)r = (r + ans[i]) % p;
		return r % p;
	}
};

3254. 长度为 K 的子数组的能量值 I

给你一个长度为 n 的整数数组 nums 和一个正整数 k 。

一个数组的 能量值 定义为:

  • 如果 所有 元素都是依次 连续 且 上升 的,那么能量值为 最大 的元素。
  • 否则为 -1 。

你需要求出 nums 中所有长度为 k 的 

子数组

 的能量值。

请你返回一个长度为 n - k + 1 的整数数组 results ,其中 results[i] 是子数组 nums[i..(i + k - 1)] 的能量值。

示例 1:

输入:nums = [1,2,3,4,3,2,5], k = 3

输出:[3,4,-1,-1,-1]

解释:

nums 中总共有 5 个长度为 3 的子数组:

  • [1, 2, 3] 中最大元素为 3 。
  • [2, 3, 4] 中最大元素为 4 。
  • [3, 4, 3] 中元素 不是 连续的。
  • [4, 3, 2] 中元素 不是 上升的。
  • [3, 2, 5] 中元素 不是 连续的。

示例 2:

输入:nums = [2,2,2,2,2], k = 4

输出:[-1,-1]

示例 3:

输入:nums = [3,2,3,2,3,2], k = 2

输出:[-1,3,-1,3,-1]

提示:

  • 1 <= n == nums.length <= 500
  • 1 <= nums[i] <= 105
  • 1 <= k <= n
class Solution {
public:
	vector<int> resultsArray(vector<int>& nums, int k) {
		int n = 0;
		for (int i = 1; i < k; i++)if (nums[i] - nums[i - 1] == 1)n++;
		vector<int>ans;
		ans.push_back((n == k - 1) ? nums[k - 1] : -1);
		for (int i = k; i < nums.size(); i++) {
			if (nums[i] - nums[i - 1] == 1)n++;
			if (nums[i - k + 1] - nums[i - k] == 1)n--;
			ans.push_back((n == k - 1) ? nums[i] : -1);
		}
		return ans;
	}
};

3255. 长度为 K 的子数组的能量值 II

给你一个长度为 n 的整数数组 nums 和一个正整数 k 。

一个数组的 能量值 定义为:

  • 如果 所有 元素都是依次 连续(即 nums[i] + 1 = nums[i + 1]i < n)且 上升 的,那么能量值为 最大 的元素。
  • 否则为 -1 。

你需要求出 nums 中所有长度为 k 的 

子数组

 的能量值。

请你返回一个长度为 n - k + 1 的整数数组 results ,其中 results[i] 是子数组 nums[i..(i + k - 1)] 的能量值。

示例 1:

输入:nums = [1,2,3,4,3,2,5], k = 3

输出:[3,4,-1,-1,-1]

解释:

nums 中总共有 5 个长度为 3 的子数组:

  • [1, 2, 3] 中最大元素为 3 。
  • [2, 3, 4] 中最大元素为 4 。
  • [3, 4, 3] 中元素 不是 连续的。
  • [4, 3, 2] 中元素 不是 上升的。
  • [3, 2, 5] 中元素 不是 连续的。

示例 2:

输入:nums = [2,2,2,2,2], k = 4

输出:[-1,-1]

示例 3:

输入:nums = [3,2,3,2,3,2], k = 2

输出:[-1,3,-1,3,-1]

提示:

  • 1 <= n == nums.length <= 105
  • 1 <= nums[i] <= 106
  • 1 <= k <= n
class Solution {
public:
	vector<int> resultsArray(vector<int>& nums, int k) {
		int n = 0;
		for (int i = 1; i < k; i++)if (nums[i] - nums[i - 1] == 1)n++;
		vector<int>ans;
		ans.push_back((n == k - 1) ? nums[k - 1] : -1);
		for (int i = k; i < nums.size(); i++) {
			if (nums[i] - nums[i - 1] == 1)n++;
			if (nums[i - k + 1] - nums[i - k] == 1)n--;
			ans.push_back((n == k - 1) ? nums[i] : -1);
		}
		return ans;
	}
};

3258. 统计满足 K 约束的子字符串数量 I

给你一个 二进制 字符串 s 和一个整数 k

如果一个 二进制字符串 满足以下任一条件,则认为该字符串满足 k 约束

  • 字符串中 0 的数量最多为 k
  • 字符串中 1 的数量最多为 k

返回一个整数,表示 s 的所有满足 k 约束 

子字符串

的数量。

示例 1:

输入:s = "10101", k = 1

输出:12

解释:

s 的所有子字符串中,除了 "1010""10101" 和 "0101" 外,其余子字符串都满足 k 约束。

示例 2:

输入:s = "1010101", k = 2

输出:25

解释:

s 的所有子字符串中,除了长度大于 5 的子字符串外,其余子字符串都满足 k 约束。

示例 3:

输入:s = "11111", k = 1

输出:15

解释:

s 的所有子字符串都满足 k 约束。

提示:

  • 1 <= s.length <= 50
  • 1 <= k <= s.length
  • s[i] 是 '0' 或 '1'
class Solution {
public:
	int countKConstraintSubstrings(string s, int k) {
		vector<vector<int>>ids(2);
		int ans = 0;
		for (int i = 0; i < s.length(); i++) {
			auto &v = ids[s[i] - '0'];
			auto &v2 = ids[1-(s[i] - '0')];
			v.push_back(i);
			int id1 = ((v.size() > k) ? v[v.size() - 1 - k] : -1);
			int id2 = ((v2.size() > k) ? v2[v2.size() - 1 - k] : -1);
			ans += i - min(id1, id2);
		}
		return ans;
	}
};

3259. 超级饮料的最大强化能量

来自未来的体育科学家给你两个整数数组 energyDrinkA 和 energyDrinkB,数组长度都等于 n。这两个数组分别代表 A、B 两种不同能量饮料每小时所能提供的强化能量。

你需要每小时饮用一种能量饮料来 最大化 你的总强化能量。然而,如果从一种能量饮料切换到另一种,你需要等待一小时来梳理身体的能量体系(在那个小时里你将不会获得任何强化能量)。

返回在接下来的 n 小时内你能获得的 最大 总强化能量。

注意 你可以选择从饮用任意一种能量饮料开始。

示例 1:

输入:energyDrinkA = [1,3,1], energyDrinkB = [3,1,1]

输出:5

解释:

要想获得 5 点强化能量,需要选择只饮用能量饮料 A(或者只饮用 B)。

示例 2:

输入:energyDrinkA = [4,1,1], energyDrinkB = [1,1,3]

输出:7

解释:

  • 第一个小时饮用能量饮料 A。
  • 切换到能量饮料 B ,在第二个小时无法获得强化能量。
  • 第三个小时饮用能量饮料 B ,并获得强化能量。

提示:

  • n == energyDrinkA.length == energyDrinkB.length
  • 3 <= n <= 105
  • 1 <= energyDrinkA[i], energyDrinkB[i] <= 105
class Solution {
public:
	long long maxEnergyBoost(vector<int>& A, vector<int>& B) {		
		long long a0 = A[0], b0 = B[0];
		if (A.size() == 1)return max(a0, b0);
		long long a1 = a0 + A[1], b1 = b0 + B[1];
		for (int i = 2; i < A.size(); i++) {
			long long a2 = max(a1, b0) + A[i],b2 = max(b1, a0) + B[i];
			a0 = a1, a1 = a2, b0 = b1, b1 = b2;
		}
		return max(a1, b1);
	}
};

3261. 统计满足 K 约束的子字符串数量 II

给你一个 二进制 字符串 s 和一个整数 k

另给你一个二维整数数组 queries ,其中 queries[i] = [li, ri] 。

如果一个 二进制字符串 满足以下任一条件,则认为该字符串满足 k 约束

  • 字符串中 0 的数量最多为 k
  • 字符串中 1 的数量最多为 k

返回一个整数数组 answer ,其中 answer[i] 表示 s[li..ri] 中满足 k 约束 的 

子字符串

 的数量。

示例 1:

输入:s = "0001111", k = 2, queries = [[0,6]]

输出:[26]

解释:

对于查询 [0, 6], s[0..6] = "0001111" 的所有子字符串中,除 s[0..5] = "000111" 和 s[0..6] = "0001111" 外,其余子字符串都满足 k 约束。

示例 2:

输入:s = "010101", k = 1, queries = [[0,5],[1,4],[2,3]]

输出:[15,9,3]

解释:

s 的所有子字符串中,长度大于 3 的子字符串都不满足 k 约束。

提示:

  • 1 <= s.length <= 105
  • s[i] 是 '0' 或 '1'
  • 1 <= k <= s.length
  • 1 <= queries.length <= 105
  • queries[i] == [li, ri]
  • 0 <= li <= ri < s.length
  • 所有查询互不相同

class Solution {
public:
	vector<long long> countKConstraintSubstrings(string s, int k, vector<vector<int>>& queries) {
		vector<vector<int>>ids(2);
		vector<int>startId;
		for (int i = 0; i < s.length(); i++) {
			auto &v = ids[s[i] - '0'];
			auto &v2 = ids[1 - (s[i] - '0')];
			v.push_back(i);
			int id1 = ((v.size() > k) ? v[v.size() - 1 - k] : -1);
			int id2 = ((v2.size() > k) ? v2[v2.size() - 1 - k] : -1);
			startId.push_back(min(id1, id2));
		}
		map<int, int>m;//反射,m[i]是满足startId[x]>=i的最小x
		for (int i = 0; i < startId.size(); i++) {
			if (m.find(startId[i]) == m.end())m[startId[i]] = i;
		}
		m[s.length()] = s.length();
		for (int i = s.length() - 1; i >= 0; i--) {
			if (m.find(i) == m.end())m[i] = m[i + 1];
		}
		map<int, long long>preSum;
		long long ps = 0;
		for (int i = 0; i < s.length(); i++) {
			ps += i - startId[i];
			preSum[i]=ps;
		}
		vector<long long> ans;
		for (auto q : queries) {
			long long s = 0;
			int id = m[q[0]];
			if (id > q[1]) {
				s = ((long long)(q[1] - q[0] + 1))*(q[1] - q[0] + 2) / 2;
			}
			else {
				s = ((long long)(id - q[0]))*(id - q[0] + 1) / 2;
				s += preSum[q[1]] - preSum[id - 1];
			}
			ans.push_back(s);
		}
		return ans;
	}
};

3264. K 次乘运算后的最终数组 I

K 次乘运算后的最终数组 II的简化版

3266. K 次乘运算后的最终数组 II

给你一个整数数组 nums ,一个整数 k  和一个整数 multiplier 。

你需要对 nums 执行 k 次操作,每次操作中:

  • 找到 nums 中的 最小 值 x ,如果存在多个最小值,选择最 前面 的一个。
  • 将 x 替换为 x * multiplier 。

k 次操作以后,你需要将 nums 中每一个数值对 109 + 7 取余。

请你返回执行完 k 次乘运算以及取余运算之后,最终的 nums 数组。

示例 1:

输入:nums = [2,1,3,5,6], k = 5, multiplier = 2

输出:[8,4,6,5,6]

解释:

操作结果
1 次操作后[2, 2, 3, 5, 6]
2 次操作后[4, 2, 3, 5, 6]
3 次操作后[4, 4, 3, 5, 6]
4 次操作后[4, 4, 6, 5, 6]
5 次操作后[8, 4, 6, 5, 6]
取余操作后[8, 4, 6, 5, 6]

示例 2:

输入:nums = [100000,2000], k = 2, multiplier = 1000000

输出:[999999307,999999993]

解释:

操作结果
1 次操作后[100000, 2000000000]
2 次操作后[100000000000, 2000000000]
取余操作后[999999307, 999999993]

提示:

  • 1 <= nums.length <= 104
  • 1 <= nums[i] <= 109
  • 1 <= k <= 109
  • 1 <= multiplier <= 106
class Solution{
public:
	vector<int> getFinalState(vector<int>& nums, int k, int multiplier) {
		if (multiplier <= 1)return nums;
		priority_queue<Node, vector<Node>, greater<Node>>q;
		long long maxVal = 0;
		Node nod;
		for (nod.id = 0; nod.id < nums.size(); nod.id++) {
			nod.val = nums[nod.id];
			maxVal = max(maxVal, nod.val);
			q.push(nod);
		}
		bool flag = false;
		while (true) {
			Node nod = q.top();
			if (nod.val * multiplier > maxVal)flag = true;
			if (flag && k%nums.size() == 0) {
				break;
			}
			q.pop();
			nod.val = nod.val * multiplier;
			maxVal = max(maxVal, nod.val);
			nums[nod.id] = nod.val % 1000000007;
			q.push(nod);
			if (--k== 0)break;
		}
		if (k) {
			long long m = MultiMulti(multiplier, k / nums.size(), 1000000007);
			for (auto &x : nums)x = x * m % 1000000007;
		}
		return nums;
	}
};

3270. 求出数字答案

给你三个  整数 num1 ,num2 和 num3 。

数字 num1 ,num2 和 num3 的数字答案 key 是一个四位数,定义如下:

  • 一开始,如果有数字 少于 四位数,给它补 前导 0 
  • 答案 key 的第 i 个数位(1 <= i <= 4)为 num1 ,num2 和 num3 第 i 个数位中的 最小 值。

请你返回三个数字 没有 前导 0 的数字答案。

示例 1:

输入:num1 = 1, num2 = 10, num3 = 1000

输出:0

解释:

补前导 0 后,num1 变为 "0001" ,num2 变为 "0010" ,num3 保持不变,为 "1000" 。

  • 数字答案 key 的第 1 个数位为 min(0, 0, 1) 。
  • 数字答案 key 的第 2 个数位为 min(0, 0, 0) 。
  • 数字答案 key 的第 3 个数位为 min(0, 1, 0) 。
  • 数字答案 key 的第 4 个数位为 min(1, 0, 0) 。

所以数字答案为 "0000" ,也就是 0 。

示例 2:

输入: num1 = 987, num2 = 879, num3 = 798

输出:777

示例 3:

输入:num1 = 1, num2 = 2, num3 = 3

输出:1

提示:

  • 1 <= num1, num2, num3 <= 9999
class Solution {
public:
	int generateKey(int num1, int num2, int num3) {
		int ans = min(num1 % 10, min(num2 % 10, num3 % 10));
		num1 /= 10, num2 /= 10, num3 /= 10;
		ans += min(num1 % 10, min(num2 % 10, num3 % 10)) * 10;
		num1 /= 10, num2 /= 10, num3 /= 10;
		ans += min(num1 % 10, min(num2 % 10, num3 % 10)) * 100;
		ans += min(num1 / 10, min(num2 / 10, num3 / 10)) * 1000;
		return ans;
	}
};

3274. 检查棋盘方格颜色是否相同

给你两个字符串 coordinate1 和 coordinate2,代表 8 x 8 国际象棋棋盘上的两个方格的坐标。

以下是棋盘的参考图。

如果这两个方格颜色相同,返回 true,否则返回 false

坐标总是表示有效的棋盘方格。坐标的格式总是先字母(表示列),再数字(表示行)。

示例 1:

输入: coordinate1 = "a1", coordinate2 = "c3"

输出: true

解释:

两个方格均为黑色。

示例 2:

输入: coordinate1 = "a1", coordinate2 = "h3"

输出: false

解释:

方格 "a1" 是黑色,而 "h3" 是白色。

提示:

  • coordinate1.length == coordinate2.length == 2
  • 'a' <= coordinate1[0], coordinate2[0] <= 'h'
  • '1' <= coordinate1[1], coordinate2[1] <= '8'
class Solution {
public:
    bool checkTwoChessboards(string s1, string s2) {
        return !((s1[0]+s1[1]+s2[0]+s2[1])&1);
    }
};

3285. 找到稳定山的下标

有 n 座山排成一列,每座山都有一个高度。给你一个整数数组 height ,其中 height[i] 表示第 i 座山的高度,再给你一个整数 threshold 。

对于下标不为 0 的一座山,如果它左侧相邻的山的高度 严格大于 threshold ,那么我们称它是 稳定 的。我们定义下标为 0 的山 不是 稳定的。

请你返回一个数组,包含所有 稳定 山的下标,你可以以 任意 顺序返回下标数组。

示例 1:

输入:height = [1,2,3,4,5], threshold = 2

输出:[3,4]

解释:

  • 下标为 3 的山是稳定的,因为 height[2] == 3 大于 threshold == 2 。
  • 下标为 4 的山是稳定的,因为 height[3] == 4 大于 threshold == 2.

示例 2:

输入:height = [10,1,10,1,10], threshold = 3

输出:[1,3]

示例 3:

输入:height = [10,1,10,1,10], threshold = 10

输出:[]

提示:

  • 2 <= n == height.length <= 100
  • 1 <= height[i] <= 100
  • 1 <= threshold <= 100
class Solution {
public:
    vector<int> stableMountains(vector<int>& height, int threshold) {
        vector<int>ans;
        for(int i=0;i<height.size()-1;i++){
            if(height[i]>threshold)ans.push_back(i+1);
        }
        return ans;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值