返回顶部

LeetCode第272场周赛

T1 5956. 找出数组中的第一个回文字符串

题目描述:给你一个字符串数组,找出第一个是回文的字符串。

思路:遍历即可

时间复杂度:\(O(\sum|s|)\)

参考代码:

class Solution {
public:
    string firstPalindrome(vector<string>& words) {
        string res;
        for(auto s : words){
            string t = s;
            reverse(t.begin() , t.end());
            if(s == t){res = s; break;}
        }
        return res;
    }
};

T2 5957. 向字符串添加空格

题目描述:给你一个字符串,再给你一个数组spacesspaces[i]表示在字符串的第\(i\)个位置的前面添加一个空格。

思路:根据题目描述直接模拟即可

时间复杂度:\(O(n)\)

参考代码:

class Solution {
public:
    string addSpaces(string s, vector<int>& spaces) {
        string res;
        int idx = 0, n = spaces.size();
        for(int i = 0 ; i < s.size() ; ++i){
            if(idx < n &&  i == spaces[idx]) res += ' ', ++idx;
            res += s[i];
        }
        return res;
    }
};

T3 5958. 股票平滑下跌阶段的数目

题目描述:给你一个整数数组 prices ,表示一支股票的历史每日股价,其中 prices[i] 是这支股票第 i 天的价格。

一个 平滑下降的阶段 定义为:对于 连续一天或者多天 ,每日股价都比 前一日股价恰好少 1 ,这个阶段第一天的股价没有限制。

请你返回 平滑下降阶段 的数目。

思路:比较明显的\(dp\),定义状态\(f_i\)表示以第\(i\)个数结尾的平滑下降阶段的数目,显然有转移方程:

\[f_i = \begin{cases} 1 & arr_i + 1 != arr_{i - 1}\\ f_{i - 1} + 1 & arr_i + 1 == arr_{i - 1} \end{cases} \]

最终答案为:\(\sum_{i = 1}^n f_i\) 。注意开long long

时间复杂度:\(O(n)\)

参考代码:

class Solution {
public:
    long long getDescentPeriods(vector<int>& prices) {
        int n = prices.size();
        vector<int> f(n + 1 , 0);
        f[1] = 1;
        for(int i = 2 ; i <= n ; ++i){
            f[i] = 1;
            if(prices[i - 1] + 1 == prices[i - 2]) f[i] += f[i - 1];
        }
        long long res = 0;
        for(auto num : f) res += num;
        return res;
    }
};

T4 5959. 使数组 K 递增的最少操作次数

题目描述:给你一个下标从 0 开始包含 n 个正整数的数组 arr ,和一个正整数 k

如果对于每个满足 \(k \leq i \leq n-1\) 的下标 \(i\) ,都有 \(arr[i-k] \leq arr[i]\) ,那么我们称 \(arr\)\(K\)递增的。

  • 比方说,

    arr = [4, 1, 5, 2, 6, 2]
    

    对于

    k = 2
    

    是 K 递增的,因为:

    • \(arr[0] <= arr[2] (4 <= 5)\)
    • \(arr[1] <= arr[3] (1 <= 2)\)
    • \(arr[2] <= arr[4] (5 <= 6)\)
    • \(arr[3] <= arr[5] (2 <= 2)\)
  • 但是,相同的数组 arr 对于 k = 1 不是 K 递增的(因为 \(arr[0] > arr[1]\)),对于 \(k = 3\) 也不是 \(K\) 递增的(因为 \(arr[0] > arr[3]\) )。

每一次 操作 中,你可以选择一个下标 i 并将 arr[i] 改成任意 正整数。

请你返回对于给定的 k ,使数组变成 \(K\) 递增的 最少操作次数

思路:显然可以把原数组分为\(k\)组,对于每一组而言,问题转化成改变最少的数字使得数组非严格单调递增,比较经典的题目,考虑求出该数组的最长非严格单调递增子序列的长度,设为\(len\),则需要修改的就是\(n - len\),做\(k\)组即可。

时间复杂度:\(O(nlogn)\)

参考代码:

class Solution {
private:
    
    int LIS(vector<int>& arr){
        
        int len = 1;
        int n = arr.size();
        vector<int> d(n + 2 , 0);
        d[len] = arr[0];
        for(int i = 1 ; i < arr.size() ; ++i){
            if(arr[i] >= d[len]) d[++len] = arr[i];
            else{
                int lr = 1 , rs = len , pos = -1;
                while(lr <= rs){
                    int mid = lr + rs >> 1;
                    if(d[mid] <= arr[i]) lr = mid + 1;
                    else rs = mid - 1, pos = mid;
                }
                d[pos] = arr[i];
            }
        }

        return n - len;
    }
public:
    int kIncreasing(vector<int>& arr, int k) {
        int res = 0;
        vector<int>f;
        int n = arr.size();
        for(int i = 0 ; i < k ; ++i){
            for(int j = i ; j < n ; j += k) f.push_back(arr[j]);
            res += LIS(f);
            f.clear();
        }
        return res;
    }
};

推荐题目:
300. 最长递增子序列
P3902 递增
P1020 [NOIP1999 普及组] 导弹拦截
P1439 【模板】最长公共子序列

posted @ 2021-12-19 13:30  cherish-lgb  阅读(23)  评论(0编辑  收藏  举报