代码随想录算法训练营第四期第六天| 454.四数相加II、383.赎金信、15.三数之和、18. 四数之和

454.四数相加II

给你四个整数数组nums1、nums2、nums3和nums4 ,数组长度都是n ,请你计算有多少个元组(i, j, k, l)能满足:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

示例1:
输入:nums1 = [1, 2], nums2 = [-2, -1], nums3 = [-1, 2], nums4 = [0, 2]
输出:2
解释:两个元组如下:
1.(0, 0, 0, 1) -> nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0
2.(1, 1, 0, 0) -> nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0

示例2:
输入:nums1 = [0], nums2 = [0], nums3 = [0], nums4 = [0]
输出:1
class Solution:
    def fourSumCount(self, nums1: int, nums2: int, nums3: int, nums4: int) -> int:
        dict_num1 = {}
        for i in range(len(nums1)):
            for j in range(len(nums2)):
                tmp = nums1[i] + nums2[j]
                if tmp not in dict_num1:
                    dict_num1[tmp] = [[i,j]]
                else:
                    dict_num1[tmp].append([i,j])
        dict_num2 = {}
        for i in range(len(nums3)):
            for j in range(len(nums4)):
                tmp = nums3[i] + nums4[j]
                if tmp not in dict_num2:
                    dict_num2[tmp] = [[i,j]]
                else:
                    dict_num2[tmp].append([i,j])
        res = 0
        for i in dict_num1:
            for j in dict_num2:
                if i + j == 0:
                    li = len(dict_num1[i])
                    lj = len(dict_num2[j])
                    tmp = li * lj
                    res += tmp
        return res

if __name__ == '__main__':
    nums1 = [1, 2]
    nums2 = [-2, -1]
    nums3 = [-1, 2]
    nums4 = [0, 2]
    tmp = Solution()
    res = tmp.fourSumCount(nums1,nums2,nums3,nums4)
    print(res)

class Solution {
public:
    int fourSumCount(vector& nums1, vector& nums2, vector& nums3, vector& nums4) {
        unordered_map map1;
        for(int i = 0; i < nums1.size(); i++){
            for(int j = 0; j < nums2.size(); j++){
                int tmp = nums1[i]+nums2[j];
                map1[tmp]++;
            }
        }
        int res = 0;
        for(int i = 0; i < nums3.size(); i++){
            for(int j = 0; j < nums4.size(); j++){
                int tmp = nums3[i] + nums4[j];
                if(map1.find(0-tmp) != map1.end()){
                    res += map1[0-tmp];
                }
            }
        }
        return res;
    }
};

看了一下解法,因为只需要求计数,所以可以直接count计数,这样可以少循环一次。

383.赎金信

给你两个字符串:ransomNote和magazine ,判断ransomNote能不能由magazine里面的字符构成。
如果可以,返回true ;否则返回false 。
magazine中的每个字符只能在ransomNote中使用一次。

示例1:
输入:ransomNote = "a", magazine = "b"
输出:false

示例2:
输入:ransomNote = "aa", magazine = "ab"
输出:false

示例3:
输入:ransomNote = "aa", magazine = "aab"
输出:true

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        dic = {}
        for i in ransomNote:
            if i not in dic:
                dic[i] = 1
            else:
                dic[i] += 1
        dic_mag = {}
        for j in magazine:
            if j not in dic_mag:
                dic_mag[j] = 1
            else:
                dic_mag[j] += 1
        for k, v in dic.items():
            tmp = dic_mag.get(k)
            if tmp is None or v > tmp:
                return False
        return True

if __name__ == '__main__':
    ransomNote = "aa"
    magazine = "aab"
    tmp = Solution()
    res = tmp.canConstruct(ransomNote,magazine)
    print(res)
class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int alpha[26] = {0};
        for(char a : magazine){
            alpha[a - 'a']++;
        }
        for(char b: ransomNote){
            alpha[b - 'a']--;
            if(alpha[b - 'a'] < 0){
                return false;
            }
        }
        return true;
    }
};

看了一下随想录,发现python有四种解法, 麻了

重写发现C++的写法很有意思

15.三数之和

给你一个整数数组nums ,判断是否存在三元组[nums[i], nums[j], nums[k]]满足i != j、i != k且
j != k ,同时还满足nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为0且不重复的三元组。
注意:答案中不可以包含重复的三元组。

示例1:
输入:nums = [-1, 0, 1, 2, -1, -4]
输出:[[-1, -1, 2], [-1, 0, 1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是[-1, 0, 1]和[-1, -1, 2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例2:
输入:nums = [0, 1, 1]
输出:[]
解释:唯一可能的三元组和不为0 。

示例3:
输入:nums = [0, 0, 0]
输出:[[0, 0, 0]]

解释:唯一可能的三元组和为0

class Solution:
    def threeSum(self, nums):
        long = len(nums)
        res = []
        nums.sort()
        for i in range(long):
            if i == long - 2:
                break
            left = i + 1
            right = long - 1
            while left < right:
                if nums[i] + nums[left] + nums[right] > 0:
                    right -= 1
                elif nums[i] + nums[left] + nums[right] < 0:
                    left += 1
                else:
                    tmp = [nums[i], nums[left], nums[right]]
                    tmp.sort()
                    if tmp not in res:
                        res.append(tmp)
                    left += 1
        return res

if __name__ == '__main__':
    nums = [-1, 0, 1, 2, -1, -4]
    nums = [0, 1, 1]
    nums = [0, 0, 0,0]
    nums = [-2, 0, 1, 1, 2]
    tmp = Solution()
    res = tmp.threeSum(nums)
    print(res)

class Solution {
public:
    vector> threeSum(vector& nums) {
        vector> res;
        sort(nums.begin(),nums.end());
        int cnt = nums.size();
        for(int i = 0; i < cnt; i++){
            int start = i + 1;
            int end = cnt - 1;
            if(nums[i] > 0){
                return res;
            }
            if (i > 0 && nums[i] == nums[i - 1]) {
                continue;
            }
            while(start < end){
                int sum = nums[i] + nums[start] + nums[end];
                if(sum == 0){
                    vector tmp;
                    tmp.push_back(nums[i]);
                    tmp.push_back(nums[start]);
                    tmp.push_back(nums[end]);
                    res.push_back(tmp);                    
                    //[-2,0,0,2,2]这个示例指引去重
                    while(end > start and nums[end] == nums[end-1]){
                        end--;
                    }
                    while(end > start and nums[start] == nums[start+1]){
                        start++;
                    }
                    start++;
                    end--;                    
                }
                else if(sum > 0){
                    end--;
                }
                else{
                    start++;
                }
            }
        }
        return res;
    }
};

18. 四数之和

给你一个由n个整数组成的数组nums ,和一个目标值target 。请你找出并返回满足下述全部条件且不重复的四元
组[nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < n
a、b、c和d互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按任意顺序返回答案 。

示例1:
输入:nums = [1, 0, -1, 0, -2, 2], target = 0
输出:[[-2, -1, 1, 2], [-2, 0, 0, 2], [-1, 0, 0, 1]]

示例2:
输入:nums = [2, 2, 2, 2, 2], target = 8
输出:[[2, 2, 2, 2]]
class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        
        nums.sort()
        n = len(nums)
        res = []
        for i in range(n):
            if i > 0 and nums[i] == nums[i - 1]: continue
            for k in range(i+1, n):
                if k > i + 1 and nums[k] == nums[k-1]: continue
                p = k + 1
                q = n - 1

                while p < q:
                    if nums[i] + nums[k] + nums[p] + nums[q] > target: q -= 1
                    elif nums[i] + nums[k] + nums[p] + nums[q] < target: p += 1
                    else:
                        res.append([nums[i], nums[k], nums[p], nums[q]])
                        while p < q and nums[p] == nums[p + 1]: p += 1
                        while p < q and nums[q] == nums[q - 1]: q -= 1
                        p += 1
                        q -= 1
        return res

第四题需要再看看,压力好大啊,这个节奏真的快

感觉现在每天睡眠质量严重不足啊

你可能感兴趣的:(算法,leetcode,职场和发展)