数据结构算法刷题(9)Nsum问题

N数之和的主要思想就是双指针,首先保证数组是排序数组,然后设置双指针left和right,不断比较left和right所指的元素和是否是target。

代码如下:

class Solution:

    def twoSum(self, nums: List[int], target: int) -> List[int]:

        num = sorted(nums) #sorted()可以保证原数组不变,sort()会改变原数组

        left = 0

        right = len(num) - 1

        answer = []

        while left < right:

            sum_num = num[left] + num[right]

            if sum_num < target:

                left += 1

            if sum_num > target:

                right -= 1

            if sum_num == target:

                if num[left] != num[right]: #两个数不相等时,用index找下标即可

                    answer = [nums.index(num[left]),nums.index(num[right])]

                else:

                    answer = [i[0] for i in list(enumerate(nums)) if i[1] == num[left]] #两个数相等时,用enumerate()找到全部的下标元素

                break

        return answer

 三数之和就用两个循环,外层循环就对三数中的一个数进行遍历,内循环就遍历该数之外的数组。同样要求数组是排序数组。

代码如下:

class Solution:

    def threeSum(self, nums: List[int]) -> List[List[int]]:

        i = 0

        num = sorted(nums)

        answer = []

        while i < len(num): #外层循环

            target = 0 - num[i] #设置target

            right = len(num) - 1

            left = i + 1

            while left < right: #内层循环

                sum_two = num[left] + num[right]

                if sum_two < target:

                    left += 1

                if sum_two > target:

                    right -= 1

                if sum_two == target:

                    if [num[i], num[right], num[left]] not in answer: #保证了后面的数不会和前面的重复

                        answer.append([num[i], num[right], num[left]])

                    left += 1

                    right -= 1

            i += 1

        return answer

按照上面三数之和的思路,遍历其中一个数字,然后调用三数之和。

class Solution:

    def treeSum(self,num,target1):

        i = 0

        answer = []

        while i < len(num):

            target = target1 - num[i]

            right = len(num) - 1

            left = i + 1

            while left < right:

                sum_two = num[left] + num[right]

                if sum_two < target:

                    left += 1

                if sum_two > target:

                    right -= 1

                if sum_two == target:

                    if [num[i], num[right], num[left]] not in answer:

                        answer.append([num[i], num[left], num[right]])

                    left += 1

                    right -= 1

            i += 1

        return answer

    def fourSum(self, nums, target):

        i = 0

        nums.sort() #先排序

        answer = []

        while i < len(nums):

            target1 = target - nums[i]

            num = nums[i+1:] #将剩余的数组传入三数之和的函数中

            anw = self.treeSum(num,target1)

            if len(anw): #如果能找到这个三数之和

                for a in anw:

                    a.insert(0,nums[i]) #将第四个数插入到结果中

                    if a not in answer: #确保不会出现重复元素

                        answer.append(a)

            i += 1

        return answer

 总结:Nsum问题都是遍历其中一个数,然后递归到两数之和,两数之和用双指针和排序解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值