LeetCode第69場雙週賽
5960. 將標題首字母大寫
題目描述:將給定的句子按照題意格式化
思路:根據題意描述即可
時間複雜度:\(O(n)\)
參考程式碼:
class Solution { public: string capitalizeTitle(string title) { stringstream text(title); string t, res; while(text >> t){ if(t.size() <= 2){ for(int i = 0 ; i < t.size() ; ++i) { if(t[i] >= 'a' && t[i] <= 'z') continue; else t[i] = t[i] - 'A' + 'a'; } } else{ int n = t.size(); if(t[0] >= 'a' && t[0] <= 'z') t[0] = t[0] - 'a' + 'A'; for(int i = 1 ; i < n ; ++ i){ if(t[i] >= 'a' && t[i] <= 'z') continue; else t[i] = t[i] - 'A' + 'a'; } } if(res.size() == 0) res += t; else res += ' ' + t; } return res; } };
5961. 連結串列最大孿生和
題目描述:給你一個連結串列,其對應的陣列為\(A\),其長度為\(n\),保證\(n\)為偶數,下標從\(0\)開始,求:
\[\mathop{max}\limits_{i = 0}^{\frac{n}{2} - 1} \{A[i] + A[n - i - 1]\} \]思路:將連結串列轉化成陣列,然後根據題意模擬即可
時間複雜度:\(O(n)\)
空間複雜度:\(O(n)\)
參考程式碼:
class Solution { public: int pairSum(ListNode* head) { vector<int> arr; while(head != nullptr){ arr.push_back(head->val); head = head->next; } int res = 0, n = arr.size(); for(int i = 0 ; i < n / 2 ; ++i){ res = max(res , arr[i] + arr[n - i - 1]); } return res; } };
5962. 連線兩字母單詞得到的最長迴文串
題目描述:給你\(n\)個長度為\(2\)的字串從中選擇任意個組成迴文串,求組成的迴文串的最大長度。
思路:使用\(map\)儲存一下前面未使用的字串,對於當前列舉的字串,若它的翻轉字串在\(map\)中,就對答案\(+4\)並將其翻轉字串對應的鍵值減一,否則將其加入\(map\)中,注意若最後還剩餘長度為\(2\)且兩個字元相同的串,則最終答案還應該\(+2\)。
時間複雜度:\(O(nlogn)\)
參考程式碼:
class Solution { public: int longestPalindrome(vector<string>& words) { vector<int>cnt(27 , 0); int res = 0; string t; map<string , int>mp; for(auto s : words){ if(s[0] == s[1]){ cnt[s[0] - 'a'] ++; res += (cnt[s[0] - 'a'] / 2) * 4; cnt[s[0] - 'a'] %= 2; } else{ t = s; reverse(t.begin() , t.end()); if(mp.count(t) && mp[t] > 0) res += 4 , mp[t]--; else mp[s]++; } } for(auto ct : cnt){ if(ct == 0) continue; res += 2; break; } return res; } };
5931. 用郵票貼滿網格圖
題目描述:給你一個二進位制矩陣,每個格子要麼是\(0\)表示空, 要麼為\(1\)表示佔據,你需要在講郵票貼在二進位制矩陣中,且滿足以下限制和要求:
- 覆蓋所有空格子。
- 不覆蓋任何被佔據的格子。
- 我們可以放入任意數目的郵票。
- 郵票可以相互有重疊的部分。
- 郵票不能旋轉。
- 郵票必須完全在矩陣內。
若存在一個放置方案滿足上述條件返回true,否則返回false。
思路:首先可以使用二維字首和用於快速判斷一個矩形中是否存在被佔據的格子,我們列舉郵票的左上角的位置,若將該郵票放在此處不會產生衝突,則就將該位置置\(1\)(使用一個新的陣列儲存)。接下來列舉每一個空格\((i , j)\),查詢其所在的位置是否被某張郵票覆蓋,也即判斷子矩陣\((max(1 , i - h + 1) , max(1 , j - w + 1)) \to (i , j)\) 內是否存在標記為\(1\)的點。此時只需對剛剛的標記陣列再做一遍二維字首和就可以對於每一個空格進行\(O(1)\)判斷。
時間複雜度:\(O(nm)\)
空間複雜度:\(O(nm)\)
參考程式碼:
class Solution {
public:
bool possibleToStamp(vector<vector<int>>& grid, int h, int w) {
int n = grid.size() , m = grid[0].size();
vector<vector<int>>a(n + 1 , vector<int>(m + 1 , 0));
vector<vector<int>>b(n + 1 , vector<int>(m + 1 , 0));
for(int i = 1 ; i <= n ; ++i){
for(int j = 1 ; j <= m ; ++j){
a[i][j] = grid[i - 1][j - 1];
a[i][j] += a[i][j - 1] + a[i - 1][j] - a[i - 1][j - 1];
}
}
//列舉郵票的左上角,因為只是問可行,不要求使用最少的 ,所以若當前左上角可以貼就貼上,否則不貼
for(int i = 1 ; i <= n ; ++i){
for(int j = 1 ; j <= m ; ++j){
int up = i + h - 1 , low = j + w - 1;
if(up > n || low > m) break;
int dx = a[up][low] - a[up][j - 1] - a[i - 1][low] + a[i - 1][j - 1];
if(dx > 0) continue;
b[i][j] = 1;
}
for(int j = 1 ; j <= m ; ++j) b[i][j] += b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1];
}
for(int i = 1 ; i <= n ; ++i){
for(int j = 1 ; j <= m ; ++j){
if(grid[i - 1][j - 1] == 1) continue;
int up = max(i - h + 1 , 1) , low = max(j - w + 1 , 1);
int dx = b[i][j] - b[i][low - 1] - b[up - 1][j] + b[up - 1][low - 1];
if(dx == 0) return false;
}
}
return true;
}
};