3つの数字の合計(シンプルでわかりやすい)

3つの数字の合計(シンプルでわかりやすい)

質問: n 個の整数を含む配列 nums が与えられた場合、a + b + c = 0 となる 3 つの要素 a、b、c が nums に存在するかどうかを判断してください。条件を満たし、重複していないトリプルをすべて見つけてください。

注: 回答に重複したトリプルを含めることはできません。

例:

配列 nums = [-1, 0, 1, 2, -1, -4] の場合、

要件を満たすトリプルのセットは [ [-1, 0, 1], [-1, -1, 2] ] です。

難易度: この問題の難しさは、重複した解を削除する方法です
使用方法: ダブルポインタ
基本的な考え方: 1 つの位置を固定し、ダブルポインタを使用して他の 2 つの位置を移動します 実行
手順:

  • 特殊なケースを削除します。配列の長さが 3 未満で、配列が空の場合は、[] が直接返されます。
  • 配列を小さいものから大きいものに並べ替えます (枝刈りを容易にし、重複を削除するため)
  • ソートされた配列を走査します。このとき、i は固定位置です。各走査ではダブル ポインターが使用されます。
    • 現在 i が指している要素がすべて 0 より大きい場合、3 つの数値 = 0 になることは不可能です (配列はソートされており、現在の i は 3 つの数値の中で最小の値であるため)。
    • 繰り返される要素に移動する場合、ソリューションの繰り返しを避けるためにスキップされます。
    • l< の場合、左ポインタ l=i+1 および右ポインタ r=n-1 とします (左ポインタは現在トラバースしている i の次のビットを指し、右ポインタは後ろから前にトラバースする終わりを指します)。 r、ループを実行します
      • sum=nums[i]+nums[l]+nums[r]、0 に等しい場合、結果に対応するインデックス位置の値を結果セットに追加します。重複排除と左右のシフトを忘れないでください。この時のポインタ。
      • 結果の合計が 0 より大きい場合は、右ポインタを左に移動します
      • 結果が 0 未満の場合は、左ポインタを右に移動します

実行可能コード

class Solution():
    def threeSum(self,nums):
        n=len(nums)
        result=[]
        #如果数组为null或者长度小于3,返回[]
        if nums==None or n<3:
            return []
        #对数组进行排序
        nums.sort()  #该方法没有返回值,但是会对列表的对象进行排序
        #遍历排序后的数组
        for i in range(n):
            #如果当前i指向的元素都大于0,则不可能出现=0的三个数了
            if nums[i]>0:
                return result
            # i 重复元素则跳过
            if i > 0 and nums[i]==nums[i-1]:
                continue
            #令左指针l=i+1,右指针r=n-1 
            l=i+1
            r=n-1
            # 当l<r时 ,执行循环
            while(l<r):
                sum=nums[i]+nums[l]+nums[r]
                # 如果等于0,将结果对应的索引位置的值加入结果集中
                if sum==0:
                    result.append([nums[i],nums[l],nums[r]])
                    #在将左指针和右指针移动的时候,先对左右指针的值,进行判断; 如果重复,直接跳过; 
                    #去重,因为 i 不变,当此时 l取的数的值与前一个数相同,所以不用在计算,直接跳
                    while l < r and nums[l]==nums[l+1]:
                        l+=1
                    #去重,因为 i不变,当此时 r 取的数的值与前一个相同,所以不用在计算
                    while l < r and nums[r]==nums[r-1]:
                        r-=1
                    #将 左指针右移,将右指针左移
                    l+=1
                    r-=1
                # 如果结果大于0,将右指针左移
                elif sum>0:
                    r-=1
                #如果结果小于0,将左指针右移
                else:
                    l+=1

        return result

:

  1. 固定位置 i と左右のポインタの重複排除動作は異なります
    固定位置:nums[i]==nums[i-1]
    左ポインタ:nums[l]==nums[l+1]
    右ポインタ: nums[r]= =nums[r-1]
    理由: これは、固定位置の重複を排除するときに、nums[i]==nums[i+1] を使用すると、重複しないオカレンスの一部が失われるためです。
    例:配列 [1,1 ,2]
    nums[i]==nums[i+1] の方法を使用します。最初の 1 を走査するとき、次の 1 は重複であると判断され、状況 [1,1,2] ] は直接スキップされます。;
    nums[i]==nums[i-1] を使用します: 最初の 1 をたどるとき、次の 1 は重複とは判断されず、[1,1,2] が追加されます。結果セット

私たちがやりたいのは、トリプルを繰り返すことはできませんが、トリプル内の要素は繰り返すことができるということです。

おすすめ

転載: blog.csdn.net/qq_42859625/article/details/129438246
おすすめ