文章目录
1. 比赛结果
2. 题目
LeetCode 1331. 数组序号转换 easy
题目链接
给你一个整数数组 arr ,请你将数组中的每个元素替换为它们排序后的序号。
序号代表了一个元素有多大。序号编号的规则如下:
- 序号从 1 开始编号。
- 一个元素越大,那么序号越大。如果两个元素相等,那么它们的序号相同。
- 每个数字的序号都应该尽可能地小。
示例 1:
输入:arr = [40,10,20,30]
输出:[4,1,2,3]
解释:40 是最大的元素。 10 是最小的元素。 20 是第二小的数字。 30 是第三小的数字。
示例 2:
输入:arr = [100,100,100]
输出:[1,1,1]
解释:所有元素有相同的序号。
示例 3:
输入:arr = [37,12,28,9,100,56,80,5,12]
输出:[5,3,4,2,8,6,7,1,3]
提示:
0 <= arr.length <= 10^5
-10^9 <= arr[i] <= 10^9
解答:
class Solution {
public:
vector<int> arrayRankTransform(vector<int>& arr) {
multimap<int,int> m;
for (int i = 0; i < arr.size(); ++i)
{
m.insert(make_pair(arr[i],i));
}
int count = 0, prev = INT_MIN;
for(auto it = m.begin(); it != m.end(); ++it)
{
if(prev != it->first)//map有序,数值与前面的不相等,排名增加
{
count++;//排名
prev = it->first;
}
arr[it->second] = count;//原来数的位置,写成排名
}
return arr;
}
};
LeetCode 1328. 破坏回文串 medium
题目链接
给你一个回文字符串 palindrome ,请你将其中 一个 字符用任意小写英文字母替换,使得结果字符串的字典序最小,且 不是 回文串。
请你返回结果字符串。如果无法做到,则返回一个空串。
示例 1:
输入:palindrome = "abccba"
输出:"aaccba"
示例 2:
输入:palindrome = "a"
输出:""
提示:
1 <= palindrome.length <= 1000
palindrome 只包含小写英文字母。
解题:
class Solution {
public:
string breakPalindrome(string palindrome) {
int i = 0, n = palindrome.size();
if(n <= 1)
return "";
while(i < n && palindrome[i] <= 'a')
i++;
if(i == n)//全部为a
{
palindrome[n-1] = 'b';//最后一个改成b
return palindrome;
}
if(n%2==1 && i ==((n-1)/2))//奇数个字符,且找到的是中间的字符可以修改
{
i++;//去下一位找,修改中间的,还是回文串
while(i < n && palindrome[i] <= 'a')
i++;
if(i == n)
{
palindrome[n-1] = 'b';
return palindrome;
}
}
palindrome[i] = 'a';
return palindrome;
}
};
LeetCode 1329. 将矩阵按对角线排序 medium
给你一个 m * n 的整数矩阵 mat ,请你将同一条对角线上的元素(从左上到右下)按升序排序后,返回排好序的矩阵。
示例:
输入:mat = [[3,3,1,1],[2,2,1,2],[1,1,1,2]]
输出:[[1,1,1,1],[1,2,2,2],[1,2,3,3]]
提示:
m == mat.length
n == mat[i].length
1 <= m, n <= 100
1 <= mat[i][j] <= 100
解题:
class Solution {
public:
vector<vector<int>> diagonalSort(vector<vector<int>>& mat) {
int m = mat.size(), n = mat[0].size();
int i = 0, x, y, k;
vector<int> v;
for( ; i < n; ++i)
{
v.clear();//临时存储
x = 0,y=i;//先把第一行开头的遍历掉
while(x < m && y < n)//在范围内
{
v.push_back(mat[x][y]);
x++,y++;//对角线移动
}
sort(v.begin(),v.end());//排序
x = 0, y = i, k =0;
while(x < m && y < n)
{
mat[x][y] = v[k];//写回数组
x++,y++,k++;
}
}
for(i=1 ; i < m; ++i)
{
v.clear();
x = i,y=0;//第一列剩余的开头的遍历掉
while(x < m && y < n)
{
v.push_back(mat[x][y]);
x++,y++;
}
sort(v.begin(),v.end());
x = i, y = 0, k =0;
while(x < m && y < n)
{
mat[x][y] = v[k];
x++,y++,k++;
}
}
return mat;
}
};
LeetCode 1330. 翻转子数组得到最大的数组值 hard
给你一个整数数组 nums 。「 数组值」定义为所有满足 0 <= i < nums.length-1
的 |nums[i]-nums[i+1]|
的和。
你可以选择给定数组的任意子数组,并将该子数组翻转。但你只能执行这个操作 一次 。
请你找到可行的最大 数组值 。
示例 1:
输入:nums = [2,3,1,5,4]
输出:10
解释:通过翻转子数组 [3,1,5] ,数组变成 [2,5,1,3,4] ,数组值为 10 。
示例 2:
输入:nums = [2,4,9,24,2,1,10]
输出:68
提示:
1 <= nums.length <= 3*10^4
-10^5 <= nums[i] <= 10^5
解题:
超时代码:(按照各种组合暴力求解,两端的变化才会改变目标值)
class Solution {
public:
int maxValueAfterReverse(vector<int>& nums) {
int i, j, n=nums.size(), val=0, maxval=INT_MIN, len;
for(i = 0; i < n-1; i++)
val += abs(nums[i]-nums[i+1]);
for(len =2; len < n; ++len)
{
for(i = 0; i+len < n; ++i)
{
if(i == 0)
maxval = max(maxval,val-abs(nums[i+len]-nums[i+len-1])+abs(nums[i+len]-nums[i]));
else if(i+len == n)
maxval = max(maxval,val-abs(nums[i]-nums[i-1])+abs(nums[i+len]-nums[i]));
else
maxval = max(maxval,val-abs(nums[i]-nums[i-1])-abs(nums[i+len]-nums[i+len-1])+abs(nums[i+len]-nums[i])+abs(nums[i+len-1]-nums[i-1]));
}
}
return maxval;
}
};
变化的值 = 增加的值
减去原来的值
增加的值:
变化的值:
一次遍历 求得变化的值前面部分的最大值,后半部分的最小值,做差就是变化的最大值。
class Solution {
public:
int maxValueAfterReverse(vector<int>& nums) {
int i, j, n = nums.size(), val = 0, maxval = 0;
for(i = 0; i < n-1; i++)
val += abs(nums[i]-nums[i+1]);
if(n <= 2)
return val;
maxval = val;
for(i = 0; i < n; ++i)
{
if(i != n-1)
maxval = max(maxval, val+abs(nums[0]-nums[i+1])-abs(nums[i]-nums[i+1]));//左边界0
if(i != 0)
maxval = max(maxval, val+abs(nums[i-1]-nums[n-1])-abs(nums[i]-nums[i-1]));//右边界n-1
}
int max1 = INT_MIN, min1 = INT_MAX;
int max2 = INT_MIN, min2 = INT_MAX;
int max3 = INT_MIN, min3 = INT_MAX;
int max4 = INT_MIN, min4 = INT_MAX;
for(i = 1; i < n; ++i)
{
max1 = max(max1, nums[i-1]+nums[i]-abs(nums[i]-nums[i-1]));
max2 = max(max2, nums[i-1]-nums[i]-abs(nums[i]-nums[i-1]));
max3 = max(max3, -nums[i-1]+nums[i]-abs(nums[i]-nums[i-1]));
max4 = max(max4, -nums[i-1]-nums[i]-abs(nums[i]-nums[i-1]));
min1 = min(min1, nums[i-1]+nums[i]+abs(nums[i]-nums[i-1]));
min2 = min(min2, nums[i-1]-nums[i]+abs(nums[i]-nums[i-1]));
min3 = min(min3, -nums[i-1]+nums[i]+abs(nums[i]-nums[i-1]));
min4 = min(min4, -nums[i-1]-nums[i]+abs(nums[i]-nums[i-1]));
}
int maxdiff = max(INT_MIN, max(max1-min1, max(max2-min2, max(max3-min3, max4-min4))));
maxval = max(maxval, val+maxdiff);
return maxval;
}
};