1. 程式人生 > >[Leetcode]Two sum(兩數之和)系列總結

[Leetcode]Two sum(兩數之和)系列總結

Two sum

題目

Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
#分析題目

  • 一個數組,還有一個目標數target,讓我們找到兩個數字,使其和為targe
  • 開啟LeetCode刷題的旅程的第一道題目,暴力求解的時間複雜度o(n2),我們優化到線性的時間複雜度來解決問題,那麼就是說只能遍歷一個數字,那麼另一個數字呢,我們可以事先將其儲存起來,使用一個HashMap,來建立數字和其座標位置之間的對映,HashMap是常數級的查詢效率,這樣,我們在遍歷陣列的時候,用target減去遍歷到的數字,就是另一個需要的數字了,直接在HashMap中查詢其是否存在即可,注意要判斷查詢到的數字不是第一個數字,比如target是4,遍歷到了一個2,那麼另外一個2不能是之前那個2,先判斷是否存在,則避免了這個問題.

程式碼

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        for(int i=0; i<nums.length; i++) {
            if(map.containsKey(target - nums[i])) {
                return new int[]{map.get(target - nums[i]), i};
            }
map.put(nums[i], i); } return null; } }

3Sum

##題目
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

  • Note:
    Elements in a triplet (a,b,c) must be in non-descending order. (ie, a ≤ b ≤ c)
    The solution set must not contain duplicate triplets.
  • For example, given array S = {-1 0 1 2 -1 -4},
    A solution set is:
    (-1, 0, 1)
    (-1, -1, 2)

分析題目

  • 本題求三個數的和為0
  • 如果先fix一個數,然後另外的兩個數使用Two Sum那種HashMap的解法,但是會有重複結果出現.所以此題並不是考我們Two Sum的解法。
  • 那麼我們來分析一下這道題的特點,要我們找出三個數且和為0,那麼除了三個數全是0的情況之外,肯定會有負數和正數,我們還是要先fix一個數,然後去找另外兩個數,使三個數的和為0.如果能更有效的定位呢?我們肯定不希望遍歷所有兩個數的組合,所以如果陣列是有序的,那麼我們就可以用雙指標以線性時間複雜度來遍歷所有滿足題意的兩個數組合。
  • 具體做法:
    -1.我們首先對原陣列進行排序,然後開始遍歷排序後的陣列,這裡注意不是遍歷到最後一個停止,而是到倒數第三個就可以了。
    -2 先做個剪枝優化,就是當遍歷到正數的時候就break,因為我們的陣列現在是有序的了,如果第一個要fix的數就是正數了,那麼後面的數字就都是正數,就永遠不會出現和為0的情況了。
    -3 然後我們還要加上重複就跳過的處理,處理方法是從第二個數開始,如果和前面的數字相等,就跳過,因為我們不想把相同的數字fix兩次。我們用兩個指標分別指向fix數字之後開始的陣列首尾兩個數,如果與fix的數相加的和current正好為0,則將這兩個數和fix的數一起存入結果中。
    -4.然後就是跳過重複數字的步驟了,兩個指標都需要檢測重複數字。如果current < 0,則我們將左邊那個指標j右移一位,使得指向的數字增大一些。同理,如果兩數之和大於0,則我們將右邊那個指標k左移一位,使得指向的數字減小一些.時間複雜度o(n2).程式碼如下:
    #程式碼
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        for(int i = 0; i < nums.length - 2; i++) {
            if (i > 0 && nums[i] == nums[i - 1]) continue;
            int j = i + 1, k = nums.length - 1;
            while(j < k) {
                int current = nums[i] + nums[j] + nums[k];
                if (current == 0) {
                    res.add(Arrays.asList(nums[i], nums[j], nums[k]));
                    while(j < k && nums[j] == nums[j + 1]) j++;
                    while(j < k && nums[k] == nums[k - 1]) k--;
                    j++;
                    k--;
                } else if (current < 0) {
                    j++;
                } else {
                    k--;
                } 
            }
        }
        return res;
    }
}

4sum

題目

Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.
Note:

  • Elements in a quadruplet (a,b,c,d) must be in non-descending order. (ie, a ≤ b ≤ c ≤ d)

  • The solution set must not contain duplicate quadruplets.
    For example, given array S = {1 0 -1 0 -2 2}, and target = 0.

    A solution set is:
    (-1, 0, 0, 1)
    (-2, -1, 1, 2)
    (-2, 0, 0, 2)

分析題目

這道題要求跟3Sum差不多,只是需求擴充套件到四個的數字的和了。我們還是可以按照3Sum中的解法,只是在外面套一層迴圈,相當於求n次3Sum。我們知道3Sum的時間複雜度是O(n2),所以如果這樣解的總時間複雜度是O(n3)。程式碼如下:

程式碼

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        int len = nums.length;
        List<List<Integer>> res = new ArrayList<>();
        Arrays.sort(nums);
        for (int i = 0; i < len - 3; i++) {
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            for (int j = i + 1; j < len - 2; j++) {
                if (j > 1 && nums[j] == nums[j - 1] && j - i > 1) {
                    continue;
                }               
                int left = j + 1, right = len - 1;
                while (left < right) {
                    int _4sum = nums[i] + nums[j] + nums[left] + nums[right];
                    if (_4sum == target) {
                        res.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
                        while (left < right && nums[left] == nums[left + 1])   left++;
                        while (left < right && nums[right] == nums[right - 1]) right--;
                        left++;
                        right--;
                    } else if (_4sum > target)
                        right--;
                    else
                        left++;
                }
            }
        }
        return res;
    }
}

相關推薦

[Leetcode]Two sum(之和)系列總結

Two sum 題目 Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume

[Leetcode] two sum 之和

cnblogs specific 等於 numbers 順序 思路 one bre end Given an array of integers, find two numbers such that they add up to a specific target num

[LeetCode刷題菜鳥集] 1.Two Sum 之和

Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each input w

leetcode 1. Two Sum(之和

解題方案 思路 1 ******- 時間複雜度: O(N^2)******- 空間複雜度: O(1)****** 暴力解法,兩輪遍歷 beats 27.6% class Solution(object): def twoSum(self, nums, targe

LeetCode】1.Two Sum 之和

給定 nums = [2, 7, 11, 15], target = 9 因為 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [0, 1] 解題思路1: 兩個迴圈,輕鬆搞定: for i in range(len(nums)): for j

LeetCode 1. Two Sum 之和

LeetCode 1. Two Sum 兩數之和 標籤: Leetcode 題目描述 給定一個整數陣列 nums 和一個目標值 target,請你在該陣列中找出和為目標值的兩個整數。 你可以假設每種輸入只會對應一個答案。但是,你不能重複利用這個陣列中同樣的元素。

leetcode-1:Two Sum 之和

題目: Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each i

Two Sum 之和的幾種解法

題目:給定一個數字列表nums,找出其中和為特定值target的兩個數,返回其下標。解法一:最常規的兩個for迴圈巢狀def twoSum(nums, target): for i in range(len(nums)): for j in range

Two sum 之和

給定一個數組和一個特定的數,使得陣列中的兩個數等於這個特定的數。找出這兩個數的下標。 Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, retur

LeetCode】167. 之和 Ⅱ - 輸入有序陣列(Two Sum II - Input array is sorted)

【 英文練習 | 中文練習 】 題目描述: 給定一個已按照升序排列 的有序陣列,找到兩個數使得它們相加之和等於目標數,函式應該返回這兩個下標值 index1 和 index2,其中 index1 必須小於 index2。 說明: 返回的下標值(index1 和 ind

[LeetCode] Sum of Two Integers 之和

Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -. Example: Given a = 1 and b = 2, return 3. Credits:Sp

leetcode 1 Two sum(相加)

題目要求 給定一個整數陣列,返回兩個數字的索引,使它們加起來成為一個特定的目標。 假設每個輸入只有一個解決方案,並且不會兩次使用相同的元素。 輸入示例 Example: Given nums = [2, 7, 11, 15], target = 9, Because

Leetcode篇:之和

給定 auth object char ext 位數 return 個數 name @author: ZZQ @software: PyCharm @file: addTwoNumbers.py @time: 2018/9/18 10:35 要求:給定兩個非空鏈表來表示兩

Lintcode 之和 系列

Lintcode 56 兩數之和 給一個整數陣列,找到兩個數使得他們的和等於一個給定的數 target。 你需要實現的函式twoSum需要返回這兩個數的下標, 並且第一個下標小於第二個下標。注意這裡下標的範圍是 0 到 n-1。 樣例 給出 numbers = [2, 7, 11, 15

leetcode第一題之和python實現

給定一個整數陣列和一個目標值,找出陣列中和為目標值的兩個數。 你可以假設每個輸入只對應一種答案,且同樣的元素不能被重複利用。 示例: 給定 nums = [2, 7, 11, 15], target = 9 因為 nums[0] + nums[1] = 2 + 7 = 9 所以返回 [

leetcode刷題--之和(簡單)

一、序言   第一次刷leetcode的題,之前從來沒有刷題然後去面試的概念,直到臨近秋招,或許是秋招結束的時候才有這個意識,原來面試是需要刷題的,面試問的問題都是千篇一律的,只要刷夠了題就差不多了,當然你的基礎也要紮實,畢竟在技術面的時候很容易露餡的。   所以奉勸各位還未畢業,在大三或大二的師弟師妹早

LeetCode之1. 之和

LeetCode之1. 兩數之和 給定一個整數陣列 nums 和一個目標值 target,請你在該陣列中找出和為目標值的 兩個 整數。 你可以假設每種輸入只會對應一個答案。但是,你不能重複利用這個陣列中同樣的元素。 示例: 給定 nums = [2,

Leetcode每日一道 -- 之和

題目連結:  https://leetcode-cn.com/problems/two-sum/description/ 題目描述:  給定一個整數陣列 nums 和一個目標值 target,請你在該陣列中找出和為目標值的&nb

LeetCode面試題--之和

給定一個整數陣列和一個目標值,找出陣列中和為目標值的兩個數。 你可以假設每個輸入只對應一種答案,且同樣的元素不能被重複利用。 示例: 給定 nums = [2, 7, 11, 15], targe

小白 初入leetcode筆記:之和(python3)

題目: 給定一個整數陣列和一個目標值,找出陣列中和為目標值的兩個數。 你可以假設每個輸入只對應一種答案,且同樣的元素不能被重複利用。 示例: 給定 nums = [2, 7, 11, 15], target = 9 因為 nums[0] + nums[1] = 2