zoukankan      html  css  js  c++  java
  • 算法题 21 findNSum (好未来,LeetCode,牛客网)

    一、三数之和:LeetCode 15

    给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

    注意:答案中不可以包含重复的三元组。

    例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
    
    满足要求的三元组集合为:
    [
      [-1, 0, 1],
      [-1, -1, 2]
    ]

    解题代码一:

    class Solution:
        def threeSum(self, nums):
            """
            :type nums: List[int]
            :rtype: List[List[int]]
            """
            result=[]
            nums.sort()
            for i in range(len(nums)-2):
                #下标i表示三个数中的第一个数
                if i>0 and nums[i]==nums[i-1]:#遇到重复的数就直接跳过,避免重复计算三元组
                    continue
                #下标j表示三个数中的第二个,从i+1开始递增;下标k表示三个数中的第三个,从len(nums)-1递减
                j,k=i+1,len(nums)-1
                while j<k:
                    sum0=nums[i]+nums[j]+nums[k]
                    if sum0<0:
                        j+=1
                    elif sum0>0:
                        k-=1
                    else:
                        result.append([nums[i],nums[j],nums[k]])
                        #如果此时j和后面的数重复,k和前面的数重复记得要直接跳过
                        while j<k and nums[j+1]==nums[j]:
                            j+=1
                        while j<k and nums[k-1]==nums[k]:
                            k-=1
                        j+=1
                        k-=1
            return result

    解题代码二:更通用,适用于Nsum

    class Solution:
        def threeSum(self, nums):
            """
            :type nums: List[int]
            :rtype: List[List[int]]
            """
    
    
            # method 2:通用方法
                
            nums.sort()
            results=[]
            self.findNSum(nums,0,3,[],results)
            return results
        
        def findNSum(self,nums,target,N,result,results):
            if N<2 or len(nums)<N or target<nums[0]*N or target>nums[-1]*N:
                return
            if N==2:
                j,k=0,len(nums)-1
                while j<k:
                    s=nums[j]+nums[k]
                    if s<target:
                        j+=1
                    elif s>target:
                        k-=1
                    else:
                        results.append(result+[nums[j],nums[k]])
                        while j<k and nums[j+1]==nums[j]:
                            j+=1
                        while j<k and nums[k-1]==nums[k]:
                            k-=1
                        j+=1
                        k-=1
            else:
                # 共有len(nums)-N+1个N元组
                for i in range(len(nums)-N+1):
                    if i==0 or (i>0 and nums[i-1]!=nums[i]):
                        self.findNSum(nums[i+1:],target-nums[i],N-1,result+[nums[i]],results)
            return         

    二、四数之和 LeetCode

    给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

    注意:

    答案中不可以包含重复的四元组。

    示例:

    给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。
    
    满足要求的四元组集合为:
    [
      [-1,  0, 0, 1],
      [-2, -1, 1, 2],
      [-2,  0, 0, 2]
    ]

    解题代码:(通用,适合于NSum)

    class Solution:
        def fourSum(self, nums, target):
            """
            :type nums: List[int]
            :type target: int
            :rtype: List[List[int]]
            """
            nums.sort()
            results=[]
            self.findNSum(nums,target,4,[],results)
            return results
        
    def findNSum(self,nums,target,N,result,results):
        if N<2 or len(nums)<N or target<nums[0]*N or target>nums[-1]*N:
            return
        if N==2:
            j,k=0,len(nums)-1
            while j<k:
                s=nums[j]+nums[k]
                if s<target:
                    j+=1
                elif s>target:
                    k-=1
                else:
                    results.append(result+[nums[j],nums[k]])
                    while j<k and nums[j+1]==nums[j]:
                        j+=1
                    while j<k and nums[k-1]==nums[k]:
                        k-=1
                    j+=1
                    k-=1
        else:
            # 共有len(nums)-N+1个N元组
            for i in range(len(nums)-N+1):
                if i==0 or (i>0 and nums[i-1]!=nums[i]):
                    self.findNSum(nums[i+1:],target-nums[i],N-1,result+[nums[i]],results)
        return 

    三、牛客网 求和

    链接:https://www.nowcoder.com/questionTerminal/11cc498832db489786f8a03c3b67d02c
    来源:牛客网

    输入两个整数 n 和 m,从数列1,2,3.......n 中随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来

    输入描述:
    每个测试输入包含2个整数,n和m


    输出描述:
    按每个组合的字典序排列输出,每行输出一种组合
    示例1

    输入

    5 5

    输出

    1 4
    2 3
    5

    解法一:改造NSum

    n, m = [int(x) for x in input().split()]
    
    def findNSum(nums, target, N, result, results):
        if N < 2 or len(nums) < N or target < nums[0]*N or target > nums[-1]*N:
            return
        if N == 2:
            j, k = 0, len(nums)-1
            while j < k:
                s = nums[j]+nums[k]
                if s < target:
                    j += 1
                elif s > target:
                    k -= 1
                else:
                    results.append(result+[nums[j], nums[k]])
                    while j < k and nums[j+1] == nums[j]:
                        j += 1
                    while j < k and nums[k-1] == nums[k]:
                        k -= 1
                    j += 1
                    k -= 1
        else:
            # 共有len(nums)-N+1个N元组
            for i in range(len(nums)-N+1):
                if i == 0 or (i > 0 and nums[i-1] != nums[i]):
                    findNSum(nums[i+1:], target-nums[i],
                             N-1, result+[nums[i]], results)
        return
     
    results = []
    nums = range(1, n+1)
    for i in range(1, n+1):
        if i == m:
            results.append([i])
    for i in range(2, n+1):
        findNSum(nums, m, i, [], results)
    res=sorted(results)
    for arr in res:
        for i in range(len(arr)):
            if i==len(arr)-1:
                print(arr[i])
            else:
                print(arr[i],end=' ')

    解法三:DFS 递归

    n,m=[int(x) for x in input().split()]
     
    def dfs(res,s,temp,n,m,k):
        if s==m:
            if temp not in res:
                res.append(temp)
                for i in range(len(temp)):
                    if i!=len(temp)-1:
                        print(temp[i],end=' ')
                    else:
                        print(temp[i])
        if k>n:
            return
        for i in range(k,n+1):
            if s+i>m:
                break
            else:
                dfs(res,s+i,temp+[i],n,m,i+1)
    res=[]
    dfs(res,0,[],n,m,1)
  • 相关阅读:
    SpringBoot security关闭验证
    BCryptPasswordEncoder 判断密码是否相同
    SpringBoot 通过jjwt快速实现token授权
    lombok的@Accessors注解3个属性说明
    lombok使用教程
    linux系统下将php和mysql命令加入到环境变量中的方法
    mysql常用的一些命令,用于查看数据库、表、字段编码
    配置windows 系统PHP系统环境变量
    MYSQL导入导出.sql文件
    windows下mysql 控制台操作
  • 原文地址:https://www.cnblogs.com/yanmk/p/9552337.html
Copyright © 2011-2022 走看看