leetcode69双周赛


竞赛链接

T1: 5960. 将标题首字母大写


思路

模拟

Code

class Solution {
public:
    string capitalizeTitle(string title) {
        title+=" ";
        int cnt=0;
        vector<string>h;
        string s="";
        for(auto& i:title){
            if(i==' ')
                h.emplace_back(s),s="",cnt++;
            else
                s+=i; 
        }
        int len=h.size();
        for(auto& i:h){
            int f=i.size();
            for(int j=0;j<f;++j){
                if(f>2){
                   if(j==0&&i[j]>='a'&&i[j]<='z')
                    i[j]-=32;
                   else if(j!=0&&i[j]>='A'&&i[j]<='Z')
                     i[j]+=32;  
                }
                if(f<=2){
                   if(i[j]>='A'&&i[j]<='Z')
                    i[j]+=32;
                }               
            }
            s+=i;   
            len--;
            if(len>0)
                s+=" ";
        }
        return s;
    }
};

复杂度分析

时间复杂度:O(n2)
空间复杂度:O(1)



T2: 5961. 链表最大孪生和


思路

遍历链表,将数据存进数组里,再按要求计算

Code

class Solution {
public:
    int pairSum(ListNode* head) {
        vector<int>ha;
        while(head){
            ha.emplace_back(head->val);
            head=head->next;
        }
        int ma=INT_MIN,n=ha.size()/2-1,len=ha.size();
        for(int i=0;i<=n;++i){
            ma=max(ma,ha[i]+ha[len-i-1]);
        }
        return ma;
    }
};

复杂度分析

  • 时间复杂度O(n)。
  • 空间复杂度O(n)。


T3: 5962. 连接两字母单词得到的最长回文串


思路

贪心+哈希表
两字母单词最多 26×26 种,我们直接用哈希表统计之后,分两位相同的单词和不同的单词分别处理。

  • 对于两位不同的单词,它需要与它的对称单词构成一对才能放入回文串中;
  • 对于两位相同的单词,它可以与它自身构成一对;同时,特别的,有且仅有一次,可以把一个两位相同的单词放在正中间。

Code

class Solution {
public:
    unordered_map<string,int>ha;
    unordered_map<string,bool>f;
    int longestPalindrome(vector<string>& words) {
        for(auto& i:words)
            ha[i]++;
        int len=0;
        int hh=0;
        bool flag=false;
        for(auto& i:ha){
            string ss=i.first;
            if(ss[0]==ss[1]){
                if(i.second%2==1)
                    flag=true;
                if(i.second%2==0)
                    len+=i.second*2;
                else if(i.second%2==1)
                    len+=(i.second-1)*2;
            }
            else{
                int cnt;
                string s="";
                s+=ss[1];
                s+=ss[0];
                if(ha.count(s)&&!f.count(s)){
                    cnt=min(ha[s],i.second);
                    len+=4*cnt;
                    f[s]=true,f[ss]=true;
                }
            }
        }
        if(flag)
            len+=2;
        return len;
    }
};

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(| ∑^2 |),其中 ∑ 表示字母表


T4: 5931. 用邮票贴满网格图


思路

二维前缀和+二维差分

由于邮票可以互相重叠,我们遵从能放就放邮票的策略,遍历所有的空位,尝试以该空位为左上角放置邮票。如果这一矩形没有出界且区域内没有被占据的格子,那么就可以放置邮票,并按照二维差分的做法将区域内的所有元素值加一。判断区域内有没有被占据的格子,可以先求出 grid 的二维前缀和,这样可以 O(1) 判断。

遍历结束后,我们需要从二维差分矩阵还原出二维计数矩阵,这可以通过对二维差分矩阵求二维前缀和求出。遍历计数矩阵,如果存在一个空格子的计数值为 0,就表明该空格子没有被邮票覆盖,返回 false,否则返回 true。

Code

class Solution {
public:
    bool possibleToStamp(vector<vector<int>> &grid, int stampHeight, int stampWidth) {
        int m = grid.size(), n = grid[0].size();
        vector<vector<int>> sum(m + 1, vector<int>(n + 1)), diff(m + 1, vector<int>(n + 1));
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) { // grid 的二维前缀和
                sum[i + 1][j + 1] = sum[i + 1][j] + sum[i][j + 1] - sum[i][j] + grid[i][j];
            }
        }

        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                int x = i + stampHeight, y = j + stampWidth; // 注意这是矩形右下角横纵坐标都 +1 后的位置
                if (x <= m && y <= n && sum[x][y] - sum[x][j] - sum[i][y] + sum[i][j] == 0) {
                    ++diff[i][j];
                    --diff[i][y];
                    --diff[x][j];
                    ++diff[x][y]; // 更新二维差分
                }
            }
        }

        // 还原二维差分矩阵对应的计数矩阵
        vector<vector<int>> cnt(m + 1, vector<int>(n + 1));
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                //相当于在一个空数组的基础上利用diff差分数组还原处理后的数组
                cnt[i + 1][j + 1] = cnt[i + 1][j] + cnt[i][j + 1] - cnt[i][j] + diff[i][j];   
                if (cnt[i + 1][j + 1] == 0 && grid[i][j] == 0) {
                    return false;
                }
            }
        }
        return true;
    }
};

复杂度分析

  • 时间复杂度:O(nm)
  • 空间复杂度:O(nm)

额外拓展

二维差分矩阵


个人总结


本次双周赛,t1看题不仔细,连wa2次直接白给,t2一眼题,t3考虑情况不清楚,又wa1,t4的话对于二维差分不太熟悉,再加上看题不仔细,然后罚坐到结束。总之,看题应该更仔细不能一味追求时间,反倒疯狂罚时,😭


文章作者: 再也不会
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 再也不会 !
  目录