LeetCode 第 18 场双周赛(188/587,前32%)

1. 比赛结果

做出来了1, 2, 3题,第4题提交超时
在这里插入图片描述

在这里插入图片描述

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;
    }
};

在这里插入图片描述
参考别人的解法:

变化的值 = 增加的值 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]) 减去原来的值 ( 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]))
增加的值: 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])\\ \}
变化的值:
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]))\\ \}
一次遍历 求得变化的值前面部分的最大值,后半部分的最小值,做差就是变化的最大值。

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;
    }
};

在这里插入图片描述

发布了599 篇原创文章 · 获赞 473 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/qq_21201267/article/details/104087738