题目链接
给你一个整数数组 arr ,请你将数组中的每个元素替换为它们排序后的序号。
序号代表了一个元素有多大。序号编号的规则如下:
示例 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;
}
};
题目链接
给你一个回文字符串 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;
}
};
题目链接
给你一个 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;
}
};
题目链接
给你一个整数数组 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;
}
};
变化的值 = 增加的值 a b s ( a [ l − 1 ] − a [ r ] ) + a b s ( a [ l ] − a [ r + 1 ] ) abs(a[l−1]−a[r])+abs(a[l]−a[r+1]) abs(a[l−1]−a[r])+abs(a[l]−a[r+1]) 减去原来的值 ( a b s ( a [ l ] − a [ l − 1 ] ) + a b s ( a [ r ] − a [ r + 1 ] ) ) (abs(a[l]−a[l−1])+abs(a[r]−a[r+1])) (abs(a[l]−a[l−1])+abs(a[r]−a[r+1]))
增加的值: a b s ( a [ l − 1 ] − a [ r ] ) + a b s ( a [ l ] − a [ r + 1 ] ) = m a x { a [ l − 1 ] + a [ l ] − ( a [ r ] + a [ r + 1 ] ) , a [ l − 1 ] − a [ l ] − ( a [ r ] − a [ r + 1 ] ) , − a [ l − 1 ] + a [ l ] − ( − a [ r ] + a [ r + 1 ] ) , − a [ l − 1 ] − a [ l ] − ( − a [ r ] − a [ r + 1 ] ) } abs(a[l−1]−a[r])+abs(a[l]−a[r+1]) =\\ max\{\\ a[l - 1] + a[l] - (a[r] + a[r+1]) ,\\ a[l - 1] - a[l] - (a[r] - a[r + 1]),\\ -a[l - 1] + a[l] - (-a[r] + a[r + 1]),\\ -a[l - 1] - a[l] - (-a[r] - a[r + 1])\\ \} abs(a[l−1]−a[r])+abs(a[l]−a[r+1])=max{a[l−1]+a[l]−(a[r]+a[r+1]),a[l−1]−a[l]−(a[r]−a[r+1]),−a[l−1]+a[l]−(−a[r]+a[r+1]),−a[l−1]−a[l]−(−a[r]−a[r+1])}
变化的值:
m a x { a [ l − 1 ] + a [ l ] − a b s ( a [ l ] − a [ l − 1 ] ) − ( a [ r ] + a [ r + 1 ] + a b s ( a [ r ] − a [ r + 1 ] ) ) , a [ l − 1 ] − a [ l ] − a b s ( a [ l ] − a [ l − 1 ] ) − ( a [ r ] − a [ r + 1 ] + a b s ( a [ r ] − a [ r + 1 ] ) ) , − a [ l − 1 ] + a [ l ] − a b s ( a [ l ] − a [ l − 1 ] ) − ( − a [ r ] + a [ r + 1 ] + a b s ( a [ r ] − a [ r + 1 ] ) ) , − a [ l − 1 ] − a [ l ] − a b s ( a [ l ] − a [ l − 1 ] ) − ( − a [ r ] − a [ r + 1 ] + a b s ( a [ r ] − a [ r + 1 ] ) ) } max\{\\ a[l - 1] + a[l] - abs(a[l] - a[l - 1]) - (a[r] + a[r + 1] + abs(a[r] - a[r + 1])),\\ a[l - 1] - a[l] - abs(a[l] - a[l - 1]) - (a[r] - a[r + 1] + abs(a[r] - a[r + 1])),\\ -a[l - 1] + a[l] - abs(a[l] - a[l - 1]) - (-a[r] + a[r + 1] + abs(a[r] - a[r + 1])),\\ -a[l - 1] - a[l] - abs(a[l] - a[l - 1]) - (-a[r] - a[r + 1] + abs(a[r] - a[r + 1]))\\ \} max{a[l−1]+a[l]−abs(a[l]−a[l−1])−(a[r]+a[r+1]+abs(a[r]−a[r+1])),a[l−1]−a[l]−abs(a[l]−a[l−1])−(a[r]−a[r+1]+abs(a[r]−a[r+1])),−a[l−1]+a[l]−abs(a[l]−a[l−1])−(−a[r]+a[r+1]+abs(a[r]−a[r+1])),−a[l−1]−a[l]−abs(a[l]−a[l−1])−(−a[r]−a[r+1]+abs(a[r]−a[r+1]))}
一次遍历 求得变化的值前面部分的最大值,后半部分的最小值,做差就是变化的最大值。
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;
}
};