Python リコウ ブラッシング問題 06 - 4 つの数字の足し算 & 身代金文字 & 3 つの数字の合計 & 4 つの数字の合計

454. 4 つの数の足し算 II

トピックへのリンク: https://leetcode.cn/problems/4sum-ii/

タイトルの説明: 4 つの整数配列 nums1、nums2、nums3、および nums4 があり、配列の長さが n であるとすると、次を満たすタプル (i、j、k、l) の数を計算してください。

0 <= i、j、k、l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0

場合:

输入: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

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/4sum-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

成し遂げる:

class Solution:
    def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
        hashmap = dict()
        for n1 in nums1:
            for n2 in nums2:
                if n1 + n2 in hashmap:
                    hashmap[n1+n2] += 1
                else:
                    hashmap[n1+n2] = 1
        count = 0
        for n3 in nums3:
            for n4 in nums4:
                key = 0-(n3+n4) # 0-(n3+n4) = n1+n2,即n1+n2+n3+n4=0
                if key in hashmap:
                    count += hashmap[key]
        return count

383. 身代金の手紙

トピックリンク: https://leetcode.cn/problems/ransom-note/)

タイトルの説明: ransomNote とmagazine という 2 つの文字列が与えられた場合、ransomNote が雑誌内の文字で構成できるかどうかを判断します。

可能な場合は true を返し、そうでない場合は false を返します。

マガジン内の各キャラクターは身代金注で 1 回のみ使用できます。

場合:

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

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

成し遂げる:

class Solution:
    def canConstruct(self, ransomNote: str, magazine: str) -> bool:
        c1 = collections.Counter(ransomNote)
        c2 = collections.Counter(magazine)
        x = c1 -c2
        if(len(x)==0):
            return True
        else:
            return False

15. 3 つの数字の合計

トピックへのリンク: https://leetcode.cn/problems/3sum/

タイトルの説明: 整数配列 nums を与え、i != j、i != k、および j != k を満たす三重項 [nums[i], nums[j], nums[k]] があるかどうかを判断し、同時に nums[i] + nums[j] + nums[k] == 0 を満たします。お願いします

合計が 0 になり、重複しないすべてのトリプルを返します。

注: 回答内で重複する 3 つの要素を使用することはできません。

場合:

输入: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] 。
注意,输出的顺序和三元组的顺序并不重要。

問題を解決するというアイデアは神 K から来ています。

リンク: https://leetcode.cn/problems/3sum/solution/3sumpai-xu-shuang-zhi-zhen-yi-dong-by-jyd/

ダブルポインタ方式で道を切り開く: まず与えられた数値をソートし、計算量は O(NlogN)
ダブルポインタ方式のアイデア: 33 個のポインタのうち左端 (最小) の数値のポインタ k を固定し、ダブル ポインタ i と j を設定します。配列のインデックス (k , len(nums))(k,len(nums)) を両端に置き、ダブルポインタで交互に中央に移動し、 nums[k] + nums[i] + nums[ を満たすデータをすべて記録します。 j] = 各固定ポインター k = 0 i、j の組み合わせ:

  • 1. nums[k] > 0 の場合、直接 Break ジャンプします。nums[j] >= nums[i] >= nums[k] > 0、つまり 33 個の数値すべてが 00 より大きいため、これは不可能です。この固定ポインタ k 結果を再度検索します。
  • 2. k > 0 および nums[k] == nums[k - 1] の場合、この要素 nums[k] はスキップされます。nums[k - 1] のすべての組み合わせが結果に追加されているため、このダブル A ポインタは検索では、繰り返される組み合わせのみが取得されます。
  • 3. 配列インデックス (k, len(nums))(k, len(nums)) の両端に i, j を設定し、i < j の場合、ループ計算 s = nums[k] + nums[i] + nums[j ] を実行し、次のルールに従ってダブル ポインターの移動を実行します。
    • s < 0 の場合、i += 1 となり、繰り返されるすべての nums[i] をスキップします。
    • s > 0 の場合、j -= 1 となり、nums[j] の繰り返しをすべてスキップします。
    • s == 0 の場合、組み合わせ [k, i, j] を res に記録し、i += 1 および j -= 1 を実行し、繰り返されるすべての nums[i] および nums[j] をスキップして、繰り返しの組み合わせが記録されないようにします。

成し遂げる:

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        res,k = [],0
        n = len(nums)
        for k in range(n - 2):
            # k>0,那么j>i>k三个值都会>0,直接跳过
            if nums[k] > 0: break
            # 跳过相同的k
            if k > 0 and nums[k] == nums[k-1]: continue
            i,j = k+1, n-1

            while i < j:
                s = nums[k] + nums[i] + nums[j]
                # 当总数小于0的时候,要让它变大,所以需要让左边的i值变大,即i+1
                if s < 0:
                    i += 1
                    while i < j and nums[i] == nums[i - 1]: i += 1
                # 当总数大于0的时候,要让它变小,所以需要让右边的j值变小,即j-1
                elif s>0:
                    j -= 1
                    while i < j and nums[j] == nums[j + 1]: j -= 1
                else:
                    res.append([nums[k],nums[i],nums[j]])
                    i += 1
                    j -= 1
                    while i < j and nums[i] == nums[i - 1]: i += 1
                    while i < j and nums[j] == nums[j + 1]: j -= 1
        return res

18. 4つの数字の合計

トピックへのリンク: https://leetcode.cn/problems/4sum/

タイトルの説明: n 個の整数で構成される配列 nums とターゲット値 target が与えられます。次のすべての条件を満たし、繰り返されない四倍子 [nums[a], nums[b], nums[c], nums[d]] を見つけて返してください (2 つの 4 倍要素が 1 対 1 に対応する場合、2 つは4 倍は繰り返されるとみなされます):

0 <= a, b, c, d < n
a、b、c、d は互いに異なります
nums[a] + nums[b] + nums[c] + nums[d] == で
返すことができるターゲット任意の順序で答えます。

場合:

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

成し遂げる:

# 双指针法
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

おすすめ

転載: blog.csdn.net/modi88/article/details/127654725