九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
LeetCode刷題 -- 雙指針篇 -- 三數(shù)之和

  好久沒有水刷算法題的博客了,也不是因?yàn)橐恢睕]寫,而是單個(gè)題目總感覺記錄下來差點(diǎn)意思。正好今天又碰到一個(gè)可以用雙指針來解決的問題,順便記錄一下。

  在我看來,雙指針并不是一種“算法”,而是一種解決算法題目的技巧,如果運(yùn)用得當(dāng)其實(shí)可以方便的解決某一種類型的問題。

  寫到這里想起來前幾天和基友吹水,關(guān)于鏈表的題目,問就是快慢指針。為什么呢?鏈表相關(guān)的題目有一些比較基礎(chǔ)又比較簡單的都很適合用快慢指針來解決。比如單向鏈表是否有環(huán),就可以利用快慢指針是否相遇來判斷。再者如秋鏈表的中間項(xiàng),可以利用快指針步長為2,慢指針步長為1,保證快指針先走來得出結(jié)果。(當(dāng)快指針走到鏈表尾部,奇數(shù)個(gè)項(xiàng)時(shí),慢指針就是中間點(diǎn);偶數(shù)個(gè)時(shí),慢指針指向的就是中間兩個(gè)項(xiàng)的左邊一項(xiàng)。)又或是求倒數(shù)第n個(gè)結(jié)點(diǎn),就可以“快”指針先走n項(xiàng),慢指針再走等等。所以看來多總結(jié)相似的解法還是有些好處的。

  廢話不扯了,來看幾道題目吧。題目來自于LeetCode,傳送門。

?

11. 盛最多水的容器

  給你 n 個(gè)非負(fù)整數(shù) a1,a2,...,an,每個(gè)數(shù)代表坐標(biāo)中的一個(gè)點(diǎn)?(i,?ai) 。在坐標(biāo)內(nèi)畫 n 條垂直線,垂直線 i?的兩個(gè)端點(diǎn)分別為?(i,?ai) 和 (i, 0)。找出其中的兩條線,使得它們與?x?軸共同構(gòu)成的容器可以容納最多的水。

說明:你不能傾斜容器,且?n?的值至少為 2。

圖中垂直線代表輸入數(shù)組 [1,8,6,2,5,4,8,3,7]。在此情況下,容器能夠容納水(表示為藍(lán)色部分)的最大值為?49。

?

示例:

輸入:[1,8,6,2,5,4,8,3,7]
輸出:49

  如果你和我一樣,一開始沒想起使用雙指針來解決這個(gè)問題的話,可能會(huì)感覺比較困擾。因?yàn)榘凑疹}目的要求,我們實(shí)際上是求得最大的面積。而這個(gè)面積又受兩個(gè)變量影響,一是高度二是長度。而當(dāng)我們確定一個(gè)面積之后,如果要去判斷下一個(gè)面積是不是更大就需要移動(dòng)“水桶的一邊”,這可能會(huì)導(dǎo)致長度和高度都發(fā)生變化。進(jìn)而與暴力求解法沒什么差別了。

  當(dāng)然如果再仔細(xì)一點(diǎn)其實(shí)會(huì)發(fā)現(xiàn),關(guān)于高度,最大面積只受兩邊高度中最矮的那個(gè)影響,傳說中的木桶效應(yīng)嘛~~。這樣我們不妨就拿數(shù)組的兩個(gè)邊界作為木桶的兩邊,來計(jì)算一個(gè)初始的面積。這樣做的好處是“長度”已經(jīng)是最大值了,接下來如果我們要移動(dòng)某一條邊,發(fā)現(xiàn)移動(dòng)后的高度還不高于移動(dòng)前的高度,我們可以直接說它的面積是會(huì)比移動(dòng)前更小的。并且,由于“木桶效應(yīng)”,我們也可以推斷每次都應(yīng)該移動(dòng)最矮的那條邊。(如果移動(dòng)的是高的邊,那么木桶的長度一定比之前小,高度一定不大于之前的高度,故面積一定比之前小)。

  看看Code吧。

 1 public class Solution { 2     public int MaxArea(int[] height) { 3         int begin = 0; 4         int end = height.Length - 1; 5  6         int result = -1; 7  8         while(begin < end) 9         {10             int temp;11             if(height[begin] > height[end])12             {13                 temp = (end-begin) * height[end];14                 end --;15             }16             else17             {18                 temp = (end-begin) * height[begin];19                 begin   ;20             }21             22             result = temp > result ? temp : result;23         }24 25         return result;26     }27 }

  官方解法有關(guān)于應(yīng)該移動(dòng)哪條邊更詳細(xì)的證明,傳送門。

?

15. 三數(shù)之和

給你一個(gè)包含 n 個(gè)整數(shù)的數(shù)組?nums,判斷?nums?中是否存在三個(gè)元素 a,b,c ,使得?a b c = 0 ?請(qǐng)你找出所有滿足條件且不重復(fù)的三元組。

注意:答案中不可以包含重復(fù)的三元組。

示例:

給定數(shù)組 nums = [-1, 0, 1, 2, -1, -4],

滿足要求的三元組集合為:
[
[-1, 0, 1],
[-1, -1, 2]
]

?

  對(duì)于原始的數(shù)組,看起來似乎只能使用暴力求解。但如果它是有序的呢,畢竟要求三個(gè)數(shù)字和為0,如果是有序數(shù)組應(yīng)該可以省去一些邊界值的情況,減少比較的次數(shù)。

  假設(shè)我們按索引的順序選取a,b,c。如果數(shù)組是有序的,那么可以推斷如果a>0或a b>0,那么一定不存在這樣的結(jié)果。所以我們可以從索引為0的位置讓a開始遍歷,然后第二個(gè)數(shù)字b選取a的下一位,c選取數(shù)組的末尾。這樣根據(jù)a b c與0的大小比較,就可以知道我們當(dāng)前的值應(yīng)該進(jìn)行怎樣的調(diào)整。如果較大,我們就移動(dòng)c,讓和變小。如果較小。我們就移動(dòng)b,讓和變大。

  Show code:

 1 public class Solution { 2         public IList<IList<int>> ThreeSum(int[] nums) 3         { 4             List<IList<int>> result = new List<IList<int>>(); 5  6             if (nums.Length < 3) 7             { 8                 return result; 9             }10 11             Array.Sort(nums);12 13             for(int i = 0; i < nums.Length - 2; i  )14             {15                 int k = i;16                 int m = i   1;17                 int n = nums.Length - 1;18 19                 while (m < n)20                 {21                     if (nums[k] > 0)22                         break;23 24                     if (nums[k]   nums[m]   nums[n] == 0)25                     {26                         var temp = new List<int>();27                         temp.Add(nums[k]);28                         temp.Add(nums[m]);29                         temp.Add(nums[n]);30 31                         result.Add(temp);32 33                         do34                         {35                             n--;36                         }37                         while (n > m && nums[n] == nums[n   1]);38 39                         do40                         {41                             m  ;42                         }43                         while (m < n && nums[m] == nums[m - 1]);44                     }45                     else if (nums[k]   nums[m]   nums[n] > 0)46                     {47                         do48                         {49                             n--;50                         }51                         while (n > m && nums[n] == nums[n   1]);52                     }53                     else54                     {55                         do56                         {57                             m  ;58                         }59                         while (m < n && nums[m] == nums[m - 1]);60                     }61                 }62 63                 do64                 {65                     i  ;66                 }67                 while (i < nums.Length && nums[i] == nums[i - 1]);68 69                 i--;70             }71 72             return result;73         }74 }

  感興趣的小伙伴也可以去搜索一些這道題目下別的解法。只能說大神實(shí)在是太厲害了,哈哈。

?

16. 最接近的三數(shù)之和

給定一個(gè)包括?n 個(gè)整數(shù)的數(shù)組?nums?和 一個(gè)目標(biāo)值?target。找出?nums?中的三個(gè)整數(shù),使得它們的和與?target?最接近。返回這三個(gè)數(shù)的和。假定每組輸入只存在唯一答案。

例如,給定數(shù)組 nums = [-1,2,1,-4], 和 target = 1.

與 target 最接近的三個(gè)數(shù)的和為 2. (-1 2 1 = 2).

  這道題和前面一道有一點(diǎn)點(diǎn)區(qū)別,不是相等,而是最接近。因此需要利用絕對(duì)值來進(jìn)行判斷。主要需要改變的地方是需要記錄一下當(dāng)前絕對(duì)值,如果不是需要更新,來幫助我們找到最接近的值。

  上代碼:

 1 public class Solution { 2         public int ThreeSumClosest(int[] nums, int target) 3         { 4             int ans = nums[0]   nums[1]   nums[2]; 5  6             var sortNums = nums.OrderBy(x => x).ToArray(); 7  8             for (int i = 0; i < sortNums.Count() - 2; i  ) 9             {10                 int start = i   1;11                 int end = sortNums.Count() - 1;12 13                 while (start < end)14                 {15                     int temp = sortNums[i]   sortNums[start]   sortNums[end];16                     if (Math.Abs(temp - target) < Math.Abs(ans - target))17                     {18                         ans = temp;19                     }20 21                     if (temp > target)22                     {23                         end--;24                     }25                     else if (temp < target)26                     {27                         start  ;28                     }29                     else30                     {31                         return target;32                     }33                 }34 35             }36 37             return ans;38         }39 }

?

  嗯,算法還是要多多練習(xí)呀。

來源:https://www.icode9.com/content-4-691901.html
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
LeetCode 912.排序數(shù)組
[Leetcode] Remove Element 刪除數(shù)組元素
【LeetCode 面試45】排序?qū)n}——把數(shù)組排成最小的數(shù)(詳解)
【小Y學(xué)算法】??每日LeetCode打卡??——49.匯總區(qū)間
刻意練習(xí):LeetCode實(shí)戰(zhàn) -- Task03. 移除元素
刷14道leetcode的總結(jié)
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服