【LeetCode】算法系列(Algorithms)(一)——2sum,3sum,3sum Closeset

本系列記錄了博主在刷LeetCode過程中的筆記。更新於2019.5.13。

ps:今天是母親節,祝所有的母親們節日快樂,健康幸福!

1. 2Sum

題目難度: easy

題目

Given an array of integers, return indices of the two numbers such that they add up to a specific target.
給定一個由整數組成的array,返回和等於某個特定目標數的兩個數的indices。

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,
給定整數[2,7,11,15],目標數9。

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
因爲nums[0]+nums[1]=2+7=9,所以返回[0,1]。

答案

方法1:暴力搜索
這個方案相信很多人都可以想到,即查詢整個array,對每個元素xx都查找一下有沒有元素等於targetxtarget-x

Java答案:

public int[] twoSum(int[] nums, int target) {
    for (int i = 0; i < nums.length; i++) {
        for (int j = i + 1; j < nums.length; j++) {
            if (nums[j] == target - nums[i]) {
                return new int[] { i, j };
            }
        }
    }
    throw new IllegalArgumentException("No two sum solution");
}

方法2: Two-pass Hash Table
爲了節省運算時間,需要有一個更有效的方法檢查元素是否存在於array中。如果存在,需要找到該元素的index。那麼什麼是管理array內的每個元素到其index映射的最好方法呢?那就是hash table(哈希表)

由此,我們以存儲空間爲代價,將查找時間從O(n)O(n)下降到了O(1)O(1)。具體實現方法是,首先建一個哈希表,隨後查表。

Java答案:

public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<>();
    for (int i = 0; i < nums.length; i++) {
        map.put(nums[i], i);
    }
    for (int i = 0; i < nums.length; i++) {
        int complement = target - nums[i];
        if (map.containsKey(complement) && map.get(complement) != i) {
            return new int[] { i, map.get(complement) };
        }
    }
    throw new IllegalArgumentException("No two sum solution");
}

在這裏插入圖片描述
方法3:其他方法

Python答案:

class Solution(object):
    def twoSum(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        
        for i in range(len(nums)):
            search_num = target-nums[i]
            if search_num in nums:
                index_b = nums.index(search_num)
                if index_b != i:
                    index_a = i
                    return index_a,index_b

在這裏插入圖片描述

C++答案:

#include <unordered_map>
#include <vector>
using namespace std;

class Solution
{
public:
    vector<int> twoSum(vector<int>& nums, int target)
    {
        unordered_map<int, size_t> N;
        vector<int> res;
        for(size_t i = 0; i < nums.size(); ++i) {
            int num = nums[i];
            if(N.count(target - num)) {
                res.push_back(i);
                res.push_back(N[target - num]);
            } else {
                N.insert({ num, i });
            }
        }
        return res;
    }
};

在這裏插入圖片描述

15. 3sum

題目難度:Medium

題目

Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
給定一個由n個整數組成的array,找到是否存在三個元素a,b,c之和等於0。
如果存在,找到所有不重複的組合。

Note:
注意:

The solution set must not contain duplicate triplets.
答案中的所有組合不能重複。

Example:
例:

Given array nums = [-1, 0, 1, 2, -1, -4],
給定矩陣nums = [-1, 0, 1, 2, -1, -4],

A solution set is:
一個解是:
[
  [-1, 0, 1],
  [-1, -1, 2]
]

答案

沒有官方答案,博主寫的python代碼,雖然不是暴力搜索但是仍然超出時間限制:

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        
        results = [];
        final_results = [];
        
        for i in range(len(nums)):
            for j in range(len(nums)):
                if i != j:
                    num_search = -nums[i]-nums[j]
                    if num_search in nums:
                        index_n = nums.index(num_search)
                        if index_n != i:
                            if index_n != j:
                                l = [nums[i],nums[j],num_search]
                                l.sort()
                                results.append(l)
        
        for i in range(len(results)):
            tmp = results[i]
            results[i] = ['a','a','a']
            if tmp in results:
                continue
            else:
                final_results.append(tmp)
                
class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        
        results = [];
        
        if len(nums) < 3:
            return results
            
        for i in range(len(nums)):
            for j in range(len(nums[i+1:])):
                search_nums = -nums[i]-nums[i+j+1]
                if search_nums in nums[i+1:]:
                    search_nums_index = nums[i+1:].index(search_nums)
                    if j != search_nums_index:
                        l = [nums[i],nums[i+j+1],search_nums]
                        l.sort()
                        if l in results:
                            continue
                        else:
                            results.append(l)
        return results

C++答案:
代碼來自於這裏

class Solution {
public:
    vector< vector<int> > threeSum(vector<int>& nums) {
        int n = nums.size();
        vector< vector<int> > res;
        if (n < 3)
            return res;
        sort(nums.begin(), nums.end());
        for(int i = 0; i < n - 2; i++)
        {
            if(i == 0 ||  (i > 0 && nums[i] != nums[i - 1]))
            {
                int left = i + 1, right = n - 1;
                int sum = 0 - nums[i];
                while(left < right)
                {
                    if(nums[left] + nums[right] == sum)
                    {
                        vector<int> vi;
                        vi.push_back(nums[i]);
                        vi.push_back(nums[left]);
                        vi.push_back(nums[right]);
                        res.push_back(vi);
                        while(left < right && nums[left] == nums[left + 1])
                            left++;
                        while(left < right && nums[right] == nums[right - 1])
                            right--;
                        left++;
                        right--;
                    }
                    else if(nums[left] + nums[right] < sum)
                        left++;
                    else
                        right--;
                }
            }
        }
        return res;
    }
};

在這裏插入圖片描述
但是博主嘗試用相同的邏輯撰寫Python代碼,仍然超出時間限制:

class Solution(object):
    def threeSum(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        
        results = []
        n = len(nums)
        
        nums.sort()
        for i in range(n):
            left = i+1
            right = n-1
            rest_num = -nums[i]
            while left < right:
                if nums[left]+nums[right]==rest_num:
                    l = [nums[i],nums[left],nums[right]]
                    if l in results:
                        left=left+1
                        right=right-1
                        continue
                    else:
                        results.append(l)
                        left=left+1
                        right=right-1
                elif nums[left]+nums[right]<rest_num:
                    left = left+1
                else:
                    right=right-1
        return results

正確Python代碼,相同思路:

class Solution:
    # @return a list of lists of length 3, [[val1,val2,val3]]
    def threeSum(self, num):
        num.sort()
        res = []
        for i in range(len(num)-2):
            if i == 0 or num[i] > num[i-1]:
                left = i + 1; right = len(num) - 1
                while left < right:
                    if num[left] + num[right] == -num[i]:
                        res.append([num[i], num[left], num[right]])
                        left += 1; right -= 1
                        while left < right and num[left] == num[left-1]: left +=1
                        while left < right and num[right] == num[right+1]: right -= 1
                    elif num[left] + num[right] < -num[i]:
                        while left < right:
                            left += 1
                            if num[left] > num[left-1]: break
                    else:
                        while left < right:
                            right -= 1
                            if num[right] < num[right+1]: break
        return res

在這裏插入圖片描述

16. 3Sum Closest

題目難度:Medium

題目

Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
給定一個由整數組成的array nums和一個目標整數target,找到nums中的三個整數,使得其和最接近target。
返回這三個整數的和。可以假設只存在一個解。

Example:
例:

Given array nums = [-1, 2, 1, -4], and target = 1.
給定array nums = [-1, 2, 1, -4]和目標target = 1

The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
最接近目標的和應該是2:(-1 + 2 + 1 = 2)。

答案

Python答案:
以下爲博主自己寫的Python版本答案

class Solution(object):
    def threeSumClosest(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: int
        """
        
        nums.sort()
        tmp_left = []
        tmp_right = []
        
        for i in range(len(nums)-2):
            obj = target-nums[i]
            left = i+1; right = len(nums)-1
            
            while left<right:
                tmp = nums[left]+nums[right]
                if tmp == obj:
                    return tmp+nums[i]
                elif tmp < obj:
                    tmp_left.append(tmp + nums[i])
                    left = left+1
                else:
                    tmp_right.append(tmp + nums[i])
                    right = right-1
                
        try:
            left_max = max(tmp_left)
            res_left = abs(left_max-target)
            left_exist = True
        except:
            left_exist = False
            
        try:
            right_min = min(tmp_right)
            res_right = abs(right_min-target)
            right_exist = True
        except:
            right_exist = False
                
        if left_exist and not right_exist:
            return left_max
        elif not left_exist and right_exist:
            return right_min
        elif left_exist and right_exist and res_left < res_right:
            return left_max
        elif left_exist and right_exist and res_left > res_right:
            return right_min
        else:
            print('Answer not found!')

更多內容,歡迎加入星球討論。
![在這裏插入圖片描述](https://img-blog.csdnimg.cn/2019070914030826.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1NodXFpYW9T,size_16,color_FFFFFF,t_70)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章