第三組
1. LeetCode 31. 下一個排列
大概思路:
- 由於是要找到下一個排列,所以變動範圍盡肯能靠後(增加的幅度更小),從陣列末尾開始的第一個降序(倒著看)排列的數到陣列末尾就是陣列的變動範圍,記為[l, r]。
- 將區間[l, r]內的數分為區間左端點和剩下的所有數兩個部分,第二部分是一個降序排列的陣列,第一部分即區間左端點的數小於第二部分第一個數。
- 要想找到區間[l, r]的下一個排列,由於第二部分已經是最大排列,所以只能改變第一部分,在第二部分找出一個數大於第一部分且最小,將其與第一部分交換位置,然後將第二部分從小到大排列,即可得到下一個排列。
- 字尾部分的下一個排列也可以得出整個陣列的下一個排列(遞迴?),若從後面找沒有降序排列數,則將整個陣列從小到大排列。
class Solution {
public:
void nextPermutation(vector<int>& nums) {
int k = nums.size() - 1;
while(k > 0 && nums[k] <= nums[k - 1])k--;
if(k <= 0)reverse(nums.begin(), nums.end());
else
{
int t = k;
while(t < nums.size() && nums[t] > nums[k - 1])t++;
swap(nums[k - 1], nums[t - 1]);
sort(nums.begin() + k, nums.end());
}
}
};
2. LeetCode 32. 最長有效括號
大概思路:
- 對於任意一個括號陣列字首,若字首中右括號數量大於左括號數量,則該字首應該被捨棄。
- 滿足第1點,並且左括號數量等於右括號數量的括號陣列是有效的。
- 用雙指標維護一個區間(左指標指向區間前一個數),維護區間左右括號數量,若左括號數等於右括號數,則更新答案;若左括號數小於右括號數,則該區間被捨棄,左指標指向右指標;若左括號數大於右括號數,則需要找到與該右括號數相匹配左括號左邊第一個左括號的位置來更新答案(最麻煩的一種情況)
- 可以利用棧來實現,棧中存放雙指標指向區間的所有左括號的位置,若右指標指向元素為左括號,則將該位置入棧;若右指標指向元素為右括號,此時若棧為空(對應第二種情況),若棧中只有一個元素(第一種情況),若棧中有多於1個元素(第三種情況)。
class Solution {
public:
int longestValidParentheses(string s) {
stack<int>a;
int res = 0;
for(int l = -1, r = 0; r < s.size(); r++)
{
if(s[r] == '(')a.push(r);
else
{
if(a.size())
{
a.pop();
if(a.size())res = max(res, r - a.top());
else res = max(res, r - l);
}
else l = r;
}
}
return res;
}
};
3. LeetCode 40. 組合總和 II
大概思路:
- 與組合總和I類似,多了一個數量限制(將整個陣列排序,若有n個相同數(記為x)相鄰,則x的數量限制為n。
- dfs,具體處理過程如下
class Solution {
public:
vector<vector<int>>ans;
vector<int>path;
vector<vector<int>> combinationSum2(vector<int>& c, int target) {
sort(c.begin(), c.end());
dfs(c, 0, target);
return ans;
}
void dfs(vector<int>c, int u, int target)
{
if(target == 0)
{
ans.push_back(path);
return;
}
if(u == c.size())return;
int k = u + 1;
while(k < c.size() && c[k] == c[u])k++;
int cnt = k - u;
for(int i = 0; i * c[u] <= target && i <= cnt; i++)
{
dfs(c, k, target - i * c[u]);
path.push_back(c[u]);
}
for(int i = 0; i * c[u] <= target && i <= cnt; i++)
path.pop_back();
}
};
4. LeetCode 41. 缺失的第一個正數
大概思路:
- 桶排序,將所有正數放入正數-x(x=1)的下標的位置。
- 從前往後掃描一遍,找到第一個a[nums[i]-1]不等於nums[i[的數
- 由於是正數(從1開始)所以x=1,可以擴充到x=其他的情形。
class Solution {
public:
int firstMissingPositive(vector<int>& nums) {
int n = nums.size();
int res = 0;
for(int i = 0; i < n; i++)
{
while(nums[i] >= 1 && nums[i] <= n && nums[nums[i] - 1] != nums[i])
swap(nums[i], nums[nums[i] - 1]);
}
for(int i = 0; i < n; i++)
if(nums[i] != i + 1)
{
res = i + 1;
break;
}
if(!res)res = n + 1;
return res;
}
};
5. LeetCode 42. 接雨水
大概思路1:
- 統計每根柱子上面能有多少雨水,求所有柱子之和即可。
- 每根柱子上方最多能接多少雨水取決於其左邊最高的柱子和右邊最高的柱子,取兩者的較小值-該柱子高度。若結果小於等於0說明該柱子上方沒有雨水。
class Solution {
public:
int trap(vector<int>& height) {
int n = height.size(), res = 0;
if(n == 0)return 0;
vector<int>left_max(n), right_max(n);
left_max[0] = height[0], right_max[n - 1] = height[n - 1];
for(int i = 1; i < n; i++)
left_max[i] = max(left_max[i - 1], height[i]);
for(int i = n - 2; i >= 0; i--)
right_max[i] = max(right_max[i + 1], height[i]);
for(int i = 1; i < n - 1; i++)
res += min(left_max[i], right_max[i]) - height[i];
return res;
}
};
大概思路2:
- 更通用也稍微麻煩一點,利用一個單調遞減棧(高度相同只保留最右邊的那個)
- 只要新訪問的元素大於等於棧頂,就一邊不斷彈出棧頂,一邊更新答案(次棧頂<=h[i]:答案加上次棧頂與棧頂之差(即h)與i到次棧頂距離差(即w)的積;次棧頂>h[i]:答案加上h[i]與棧頂之差(即h)與i到次棧頂距離差(即w)的積)
- 程式碼中棧頂用last表示,次棧頂用stk,top()表示,棧中存放下標(計算w要用到)。
class Solution {
public:
int trap(vector<int>& h) {
stack<int>stk;
int n = h.size(), res = 0;
for(int i = 0; i < n; i++)
{
int last = 0;
while(stk.size() && h[stk.top()] <= h[i])
{
res += (h[stk.top()] - last) * (i - stk.top() - 1);
last = h[stk.top()];
stk.pop();
}
if(stk.size())res += (h[i] - last) * (i - stk.top() - 1);
stk.push(i);
}
return res;
}
};
相關文章
- nginx事件模組 -- 第三篇Nginx事件
- Python模組、第三方模組安裝、模組匯入教程Python
- python第三天(list,元組,dictionary)Python
- 09 第三方模組 pyinstaller requests
- 第三次小組站立會議
- 正規表示式 第三篇:分組匹配
- 在樂位元組學習的第三天
- Python怎麼安裝第三方模組Python
- vscode 如何debug第三方模組原始碼VSCode原始碼
- day38-常見第三方模組
- py 第三方模組匯入(安裝)
- 第九組【團隊作業】第三週作業4
- 第六組【團隊作業】第三週作業4
- 第六組【團隊作業】第三週作業2
- 第五組【團隊作業】第三週作業1
- 第八組【團隊作業】第三週作業3
- 第八組【團隊作業】第三週作業1
- 第一組【團隊作業】第三週作業2
- 第七組【團隊作業】第三週作業4
- Mysql架構與內部模組-第三章MySql架構
- Vue 中如何正確引入第三方模組Vue
- 第三組【團隊作業】第四周作業3
- Python 安裝第三方模組的三種方法Python
- Selenium學習第三天--模組化設計用例
- Python3安裝第三方模組的詳細教程Python
- .NET Emit 入門教程:第三部分:構建模組(Module)MIT
- Python3 安裝第三方模組的二種方法Python
- 2016年藍橋杯C/C++組省賽第三題--湊算式C++
- itchat—python實現呼叫微信介面的第三方模組Python
- keycloak~為keycloak-services專案新增第三方模組(首創)
- 《Terraform 101 從入門到實踐》 第三章 Modules模組化ORM
- 計算機組成與設計 讀書筆記——第三章計算機筆記
- 第三篇:低功耗模組Air724UG硬體設計手冊AI
- 第三組【團隊作業】第二週使用者調研作業2
- 【M5Stack物聯網開發】第三章 螢幕模組
- 使用 Abp.Zero 搭建第三方登入模組(一):原理篇
- Python學習筆記-基礎篇(14)-安裝第三方模組Python筆記
- 第三