15. 3Sum --- Medium
16. 3Sum Closest --- Medium
560. Subarray Sum Equals K --- Medium
189. Rotate Array --- Medium
1. 三數(shù)之和等于0 (Leetcode 15)
思路:
暴力解法 - for循環(huán)3輪登颓,找到結果集,去重。但這效率太低,需要更高效的方法。
很容易想到先排序惩阶,再處理。快排愉粤,o(n * log n)時間復雜度。
接下來遍歷該數(shù)組拿撩,對于其中的每一個元素nums[i]衣厘,找到另外兩個元素nums[j] + nums[k] == nums[i].
其中對于每一個元素nums[i], j 初始化為 i+1, k 初始化為 length -1.
根據nums[j] + nums[k] 與 nums[i] 的大小比較,決定 j 往后移動,或者 k 往前移動影暴,找滿足條件的結果错邦。
另外,需要注意型宙,結果的list是不能包含重復組合的撬呢。
那么在遍歷過程中,有兩個地方需要處理好妆兑,才能把重復組合去掉:第 1 點是魂拦,遍歷nums,移到 i搁嗓,如果nums[i] == nums[i - 1]芯勘,那么當前的 i 是不需要被處理的,直接continue就好谱姓;第 2 點是借尿,對于每一個nums[i],在移動 相應的 j,k指針時屉来,每當找到一個結果路翻,需要判斷 j 后面的元素,以及 k 前面的元素茄靠,是不是與當前 j茂契,k指向的元素相等,如果相等慨绳,直接將 j 往后移動掉冶,將 k 往前移動。
2. 最接近指定值的三數(shù)之和 (Leetcode 16)
思路:
與上一道3Sum比較類似脐雪。先排序厌小。
for循環(huán)遍歷nums,對于每一個nums[i], 用兩個指針 j, k 遍歷后面的元素战秋,初始化 j = i +1, k = length - 1. 定義一個變量 closest 存放最終結果璧亚,初始化為 nums[0] + nums[1] + nums[2].
對于每一輪循環(huán):
比較 mums[i] + nums[j] + noms[k] - target 的絕對值,與 closest - target 的絕對值脂信,兩者的大小癣蟋。如果前者小,更新closest的值為前者的值狰闪。
比較 nums[j] + nums[k] 與 target - nums[i] 的大小疯搅,如果前者大,則將 指針 k 往前移埋泵,如果前者小幔欧,則將指針 j 往后移,若兩者相等,則直接return target作為最終結果琐馆。
循環(huán)結束规阀,closest的值即為最終結果。
3. 連續(xù)子數(shù)組的和為指定值K瘦麸,求這樣的子數(shù)組的個數(shù) (Leetcode 560)
思路:
對于求連續(xù)子數(shù)組的和谁撼,想到可以先計算出數(shù)組data[i],data[i] 存放的是從第 0 到第 i 個元素的和滋饲。
有了data[]數(shù)組之后厉碟,那么找和為 K 的連續(xù)子數(shù)組,等同于找data[i] 和 data[j] 的差值為 K 的情況屠缭,就可以箍鼓。但是,這樣時間效率很低呵曹,需要N方的時間復雜度款咖。有沒有更好的方法呢?有奄喂,不過比較巧妙铐殃。
對于data[i], 如果 i 之前,有某個(或者某幾個)data元素的值為 data[i] - k跨新,那么富腊,data[i] 減去這樣的元素的值,結果為K域帐,那么這樣的子數(shù)組赘被,就是要找的子數(shù)組。這樣的元素的個數(shù)肖揣,就是以nums[i]結尾民假,和為K的子數(shù)組,的個數(shù)龙优。
那么阳欲,可以遍歷data[]數(shù)組,同時用一個HashMap<Integer, Integer>存放data[i]出現(xiàn)的次數(shù)陋率,key為data[i],value為data[i]出現(xiàn)的次數(shù)。
對于data[i]秽晚,先去hashmap里找key為 data[i] - k 相應的value瓦糟,如果有,那么value就是以nums[i]結尾赴蝇,符合條件子數(shù)組的個數(shù)菩浙。如果沒有,那就沒有唄。
再將data[i] 作為key劲蜻,加入hashmap陆淀,值設置為1,或者增加1.
遍歷時先嬉,注意有種特殊情況轧苫,data[i] - k == 0, 也就是data[i] 本身就等于k,這時疫蔓,結果直接加1含懊,同時再去hashmap里找data[i]作為key相應的value,最后也要將data[i]作為key衅胀,再放回hashmap.
整個過程處理好岔乔,是o(n)的時間復雜度。
4. 根據給定K滚躯,旋轉數(shù)組(Leetcode 189)
思路:
仔細看看Input和Output雏门,有一個很巧妙的規(guī)律。
先將數(shù)組整個反轉掸掏。接著將前k個反轉茁影,后面length - k個再反轉。就得到Output阅束。
要注意 k 可能大于數(shù)組長度呼胚,所以要先對k取模。