100264. 最长的严格递增或递减子数组
给你一个整数数组 nums
。
返回数组 nums
中 严格递增 或 严格递减 的最长非空子数组的长度。
示例 1:
输入: nums = [1,4,3,3,2]
输出: 2
解释:
nums
中严格递增的子数组有[1]
、[2]
、[3]
、[3]
、[4]
以及 [1,4]
。
nums
中严格递减的子数组有[1]
、[2]
、[3]
、[3]
、[4]
、[3,2]
以及 [4,3]
。
因此,返回 2
。
示例 2:
输入: nums = [3,3,3,3]
输出: 1
解释:
nums
中严格递增的子数组有 [3]
、[3]
、[3]
以及 [3]
。
nums
中严格递减的子数组有 [3]
、[3]
、[3]
以及 [3]
。
因此,返回 1
。
示例 3:
输入: nums = [3,2,1]
输出: 3
解释:
nums
中严格递增的子数组有 [3]
、[2]
以及 [1]
。
nums
中严格递减的子数组有 [3]
、[2]
、[1]
、[3,2]
、[2,1]
以及 [3,2,1]
。
因此,返回 3
。
提示:
1 <= nums.length <= 50
1 <= nums[i] <= 50
题解:分别判断递增和递减
class Solution {
public:
int longestMonotonicSubarray(vector<int>& nums) {
int res = 1, t = 1;
for(int i=1; i<nums.size(); i++){
if(nums[i] > nums[i-1]){
t++;
}else{
t = 1;
}
res = max(res, t);
}
t = 1;
for(int i=1; i<nums.size(); i++){
if(nums[i] < nums[i-1]){
t++;
}else{
t = 1;
}
res = max(res, t);
}
return res;
}
};
100242. 满足距离约束且字典序最小的字符串
给你一个字符串 s
和一个整数 k
。
定义函数 distance(s1, s2)
,用于衡量两个长度为 n
的字符串 s1
和 s2
之间的距离,即:
- 字符
'a'
到'z'
按 循环 顺序排列,对于区间[0, n - 1]
中的i
,计算所有「s1[i]
和s2[i]
之间 最小距离」的 和 。
例如,distance("ab", "cd") == 4
,且 distance("a", "z") == 1
。
你可以对字符串 s
执行 任意次 操作。在每次操作中,可以将 s
中的一个字母 改变 为 任意 其他小写英文字母。
返回一个字符串,表示在执行一些操作后你可以得到的 字典序最小 的字符串 t
,且满足 distance(s, t) <= k
。
示例 1:
输入: s = "zbbz", k = 3
输出: "aaaz"
解释: 在这个例子中,可以执行以下操作:
将 s[0] 改为 'a' ,s 变为 "abbz" 。
将 s[1] 改为 'a' ,s 变为 "aabz" 。
将 s[2] 改为 'a' ,s 变为 "aaaz" 。
"zbbz" 和 "aaaz" 之间的距离等于 k = 3 。
可以证明 "aaaz" 是在任意次操作后能够得到的字典序最小的字符串。
因此,答案是 "aaaz" 。
示例 2:
输入: s = "xaxcd", k = 4
输出: "aawcd"
解释: 在这个例子中,可以执行以下操作:
将 s[0] 改为 'a' ,s 变为 "aaxcd" 。
将 s[2] 改为 'w' ,s 变为 "aawcd" 。
"xaxcd" 和 "aawcd" 之间的距离等于 k = 4 。
可以证明 "aawcd" 是在任意次操作后能够得到的字典序最小的字符串。
因此,答案是 "aawcd" 。
示例 3:
输入: s = "lol", k = 0
输出: "lol"
解释: 在这个例子中,k = 0,更改任何字符都会使得距离大于 0 。
因此,答案是 "lol" 。
提示:
1 <= s.length <= 100
0 <= k <= 2000
s
只包含小写英文字母。
题解:模拟
class Solution {
public:
string getSmallestString(string s, int k) {
int n = s.size();
for(int i=0; i<n; i++){
int minv = min(s[i]-'a', 'z'-s[i]+1);
if(k <= 0){
continue;
}
if(k >=minv){
s[i] = 'a';
}else{
s[i] = s[i]-k;
}
k -= minv;
}
return s;
}
};
3107. 使数组中位数等于 K 的最少操作数
给你一个整数数组 nums
和一个 非负 整数 k
。
一次操作中,你可以选择任一下标 i
,然后将 nums[i]
加 1
或者减 1
。
请你返回将 nums
中位数 变为 k
所需要的 最少 操作次数。
一个数组的 中位数 指的是数组按 非递减 顺序排序后最中间的元素。如果数组长度为偶数,我们选择中间两个数的较大值为中位数。
示例 1:
输入: nums = [2,5,6,8,5], k = 4
输出: 2
解释: 我们将 nums[1]
和 nums[4]
减 1
得到 [2, 4, 6, 8, 4]
。现在数组的中位数等于 k
。所以答案为 2 。
示例 2:
输入: nums = [2,5,6,8,5], k = 7
输出: 3
解释: 我们将 nums[1]
增加 1 两次,并且将 nums[2]
增加 1 一次,得到 [2, 7, 7, 8, 5]
。结果数组的中位数等于 k
。所以答案为 3 。
示例 3:
输入: nums = [1,2,3,4,5,6], k = 4
输出: 0
解释: 数组中位数已经等于 k
了,所以不需要进行任何操作。
提示:
1 <= nums.length <= 2 * 105
1 <= nums[i] <= 109
1 <= k <= 109
题解:思考题
class Solution {
public:
long long minOperationsToMakeMedianK(vector<int>& nums, int k) {
sort(nums.begin(), nums.end());
long long res = 0;
int n = nums.size();
for(int i=n/2; i>=0; i--){
if(i == n/2){
res += abs(k - nums[i]);
continue;
}
if(nums[i] > k){
res += nums[i] - k;
}else{
break;
}
}
for(int i=(n/2)+1; i<n; i++){
if(nums[i] < k){
res += k - nums[i];
}else break;
}
return res;
}
};
100244. 带权图里旅途的最小代价
给你一个 n
个节点的带权无向图,节点编号为 0
到 n - 1
。
给你一个整数 n
和一个数组 edges
,其中 edges[i] = [ui, vi, wi]
表示节点 ui
和 vi
之间有一条权值为 wi
的无向边。
在图中,一趟旅途包含一系列节点和边。旅途开始和结束点都是图中的节点,且图中存在连接旅途中相邻节点的边。注意,一趟旅途可能访问同一条边或者同一个节点多次。
如果旅途开始于节点 u
,结束于节点 v
,我们定义这一趟旅途的 代价 是经过的边权按位与 AND
的结果。换句话说,如果经过的边对应的边权为 w0, w1, w2, ..., wk
,那么代价为w0 & w1 & w2 & ... & wk
,其中 &
表示按位与 AND
操作。
给你一个二维数组 query
,其中 query[i] = [si, ti]
。对于每一个查询,你需要找出从节点开始 si
,在节点 ti
处结束的旅途的最小代价。如果不存在这样的旅途,答案为 -1
。
返回数组 answer
,其中 answer[i]
表示对于查询 i
的 最小 旅途代价。
示例 1:
输入: n = 5, edges = [[0,1,7],[1,3,7],[1,2,1]], query = [[0,3],[3,4]]
输出: [1,-1]
解释:
第一个查询想要得到代价为 1 的旅途,我们依次访问:0->1
(边权为 7 )1->2
(边权为 1 )2->1
(边权为 1 )1->3
(边权为 7 )。
第二个查询中,无法从节点 3 到节点 4 ,所以答案为 -1 。
示例 2:
输入: n = 3, edges = [[0,2,7],[0,1,15],[1,2,6],[1,2,1]], query = [[1,2]]
输出: [0]
解释:
第一个查询想要得到代价为 0 的旅途,我们依次访问:1->2
(边权为 1 ),2->1
(边权 为 6 ),1->2
(边权为 1 )。
提示:
1 <= n <= 105
0 <= edges.length <= 105
edges[i].length == 3
0 <= ui, vi <= n - 1
ui != vi
0 <= wi <= 105
1 <= query.length <= 105
query[i].length == 2
0 <= si, ti <= n - 1
题解:并查集
class Solution {
public:
vector<int> p, g;
int find(int x){
if(p[x] != x){
p[x] = find(p[x]);
}
return p[x];
}
vector<int> minimumCost(int n, vector<vector<int>>& edges, vector<vector<int>>& query) {
p.resize(n);
for(int i=0; i<n; i++) p[i] = i;
g.resize(n, -1);
for(auto e : edges){
auto a = find(e[0]), b = find(e[1]), w = e[2];
g[b] &= w;
if(a != b){
p[a] = b;
g[b] &= g[a];
}
}
vector<int> res;
for(auto q : query){
int a = q[0], b = q[1];
if(a == b){
res.push_back(0);
}else if(find(a) != find(b)){
res.push_back(-1);
}else{
res.push_back(g[find(a)]);
}
}
return res;
}
};