Leetcode刷題防忘錄(十一)

2021-09-26 08:06:34 字數 4756 閱讀 9824

目錄

4sum(多指標遍歷,中等)

merge-intervals(遍歷,中等)

spiral-matrix(二維矩陣,中等)

3sum(遍歷,中等)

two-sum(遍歷,簡單)

給定乙個包含 n 個整數的陣列 nums 和乙個目標值 target,判斷 nums 中是否存在四個元素 a,b,c 和 d ,使得 a + b + c + d 的值與 target 相等?找出所有滿足條件且不重複的四元組。

注意:答案中不可以包含重複的四元組。

示例:給定陣列 nums = [1, 0, -1, 0, -2, 2],和 target = 0。

滿足要求的四元組集合為:

[[-1,  0, 0, 1],

[-2, -1, 1, 2],

[-2,  0, 0, 2]

]思路

先需要將整個序列作個排序,從小到大排序。

sort(num.begin(),num.end());
然後,開始迴圈,設定兩個迴圈變數i和j,且j時常保持在i的後面,開始迴圈。

for(int i=0;i進入後是乙個大的while迴圈,left從首位開始,right從末位遍歷,迴圈條件left < right,當兩個指標相交的時候,整個序列已經都遍歷一遍了。進入while迴圈後,先將四數求和,如果所求之和等於目標值,即將該四個數存到temp裡面,並把保持到st裡面,因為st是乙個set型別的,保證裡面的元素不會重複。去除重複組合。

int sum=num[i]+num[j]+num[left]+num[right];

if(sum==target)

如果不等於目標值,就分兩種情況進行,因為之前已經將整個序列從小到大排列了,如果sum最後,迴圈結束後,這條語句定義了乙個名為it的變數,它的資料型別是由set>定義的iterator型別。並使用迭代器讀取set>中的每乙個元素。

具體用法見:

set>::iterator it;

for(it=st.begin();it!=st.end();it++)

res.push_back(*it);

完整code

//與3sum思路類似,只不過這次需要先固定兩個數,然後雙指標找,用set去除重複組合

class solution

};

給出乙個區間的集合,請合併所有重疊的區間。

示例 1:

輸入: [[1,3],[2,6],[8,10],[15,18]]        輸出: [[1,6],[8,10],[15,18]]

解釋: 區間 [1,3] 和 [2,6] 重疊, 將它們合併為 [1,6].

示例 2:

輸入: [[1,4],[4,5]]         輸出: [[1,5]]

解釋: 區間 [1,4] 和 [4,5] 可被視為重疊區間。

思路

本題先定義了乙個型別為interval型別的vector,我也弄不清是啥,但姑且看裡面存兩個值,乙個是乙個序列的開頭另乙個是序列的結尾。姑且就這樣認為吧,沒什麼大的影響。

首先,需要將原始序列進行排序,這裡用的sort函式輸入三個引數的用法,

第乙個引數 一般為 排序的起始點(vector.begin()(起點) 或者其他位置);

第二個引數 一般為 排序的終止點(vector.end() (終點) 或者其他位置);

第三個引數是排序函式(對於一些複雜的結構 比如pair 我們需要定義排序規則);

前兩個引數是起點和終點位置,本**中專門定義了乙個cmp函式作為排序函式,大概是因為interval這個結構體比較特殊吧,cmp要求,只比較interval結構體的第乙個值,來決定這個結構的大小。

static bool cmp(const interval &a, const interval &b)

};

接著進入乙個for迴圈,如果序列的起始值小於上乙個序列的終止值,說明這兩個序列存在交叉,那麼就取這兩個序列末尾最長的值作為這兩個序列的終止值

if(result.back().end >= intervals[i].start)

result.back().end = max(result.back().end, intervals[i].end);

否則,就當作乙個新的序列存進去。 

完整code

/**

* definition for an interval.

* struct interval

* interval(int s, int e) : start(s), end(e) {}

* };

*/class solution

return result;

}static bool cmp(const interval &a, const interval &b)

};

思路

首先設定上下左右邊界

其次向右移動到最右,此時第一行因為已經使用過了,可以將其從圖中刪去,體現在**中就是重新定義上邊界

判斷若重新定義後,上下邊界交錯,表明螺旋矩陣遍歷結束,跳出迴圈,返回答案

若上下邊界不交錯,則遍歷還未結束,接著向下向左向上移動,操作過程與第一,二步同理

不斷迴圈以上步驟,直到某兩條邊界交錯,跳出迴圈,返回答案

照著**看的話,先需要分清楚的是for迴圈如果下面沒加{},說明只對下面的一條語句有效,故,**中的if判斷,都不屬於for迴圈,而是屬於while。其次,前置自增的用法,前置自增就是先進行自增,然後再和相關語句執行,那麼,**思路就很明顯了,先是for迴圈,將上、下行或,左、右列給遍歷完,然後,自增自減,完了之後再和if條件比較。一有符合要要求的,就中止while。遍歷結束。

這樣的好處是,不需要考慮到底最後一次是停留在了那行或者那列,直接在每個位置都判斷一次,這樣就省事兒了。

完整code

class solution 

return ans;

}};

給定乙個包含 n 個整數的陣列 nums,判斷 nums 中是否存在三個元素 a,b,c ,使得 a + b + c = 0 ?找出所有滿足條件且不重複的三元組。

注意:答案中不可以包含重複的三元組。

例如, 給定陣列 nums = [-1, 0, 1, 2, -1, -4],

滿足要求的三元組集合為:

[[-1, 0, 1],

[-1, -1, 2]

]思路

用雙指標以線性時間複雜度來遍歷所有滿足題意的兩個數組合。對原陣列進行排序,然後開始遍歷排序後的陣列,這裡注意不是遍歷到最後乙個停止,而是到倒數第三個就可以了。這裡可以先做個剪枝優化,就是當遍歷到正數的時候就 break,為啥呢,因為陣列現在是有序的了,如果第乙個要 fix 的數就是正數了,則後面的數字就都是正數,就永遠不會出現和為0的情況了。然後還要加上重複就跳過的處理,處理方法是從第二個數開始,如果和前面的數字相等,就跳過,因為不想把相同的數字fix兩次。對於遍歷到的數,用0減去這個 fix 的數得到乙個 target,然後只需要再之後找到兩個數之和等於 target 即可。用兩個指標分別指向 fix 數字之後開始的陣列首尾兩個數,如果兩個數和正好為 target,則將這兩個數和 fix 的數一起存入結果中。然後就是跳過重複數字的步驟了,兩個指標都需要檢測重複數字。如果兩數之和小於 target,則將左邊那個指標i右移一位,使得指向的數字增大一些。同理,如果兩數之和大於 target,則將右邊那個指標j左移一位,使得指向的數字減小一些,

引用:完整code

class solution ;

for (int k = 0; k < (int)nums.size() - 2; ++k) );

while (i < j && nums[i] == nums[i + 1]) ++i;

while (i < j && nums[j] == nums[j - 1]) --j;

++i; --j;

} else if (nums[i] + nums[j] < target) ++i;

else --j;}}

return res;

}};

給定乙個整數陣列 nums 和乙個目標值 target,請你在該陣列中找出和為目標值的那 兩個 整數,並返回他們的陣列下標。

你可以假設每種輸入只會對應乙個答案。但是,你不能重複利用這個陣列中同樣的元素。

示例:給定 nums = [2, 7, 11, 15], target = 9

因為 nums[0] + nums[1] = 2 + 7 = 9

所以返回 [0, 1]

思路

利用字典,將所有值都弄到字典中去序列的每個值作字典鍵,序列對應的下標作字典值。,接著在字典裡面找有沒有search = target-nums[i],有,而且不是同乙個數的,就把下標給push到res裡面。

完整code

class solution 

for (int i = 0; i < numbers.size(); i++)

}return res;

}};

Leetcode刷題防忘錄(四)

目錄 valid parentheses 棧,簡單 search in rotated sorted array 查詢,中等 search in rotated sorted array ii 查詢,中等 word search 回溯,dfs,中等 combinations 回溯,dfs,中等 題目...

Leetcode刷題防忘錄(十)

目錄 climbing stairs 動態規劃,簡單 reverse integer 進製,簡單 permutations 全排列,簡單 powx n 分治,簡單 sqrtx 分治,簡單 假設你正在爬樓梯。需要 n 階你才能到達樓頂。每次你可以爬 1 或 2 個台階。你有多少種不同的方法可以爬到樓頂...

每日程式設計(十一) leetcode刷題

題目 平衡二叉樹 題目描述 給定乙個二叉樹,判斷它是否是高度平衡的二叉樹。本題中,一棵高度平衡二叉樹定義為 乙個二叉樹每個節點 的左右兩個子樹的高度差的絕對值不超過1。示例 1 給定二叉樹 3,9,20,null,null,15,7 3 9 20 15 7返回true。分析 沒什麼可說的,雙遞迴,先...