zoukankan      html  css  js  c++  java
  • 四数之和

    给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + 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 = [], target = 0
    输出:[]
    

    提示:

    0 <= nums.length <= 200
    -109 <= nums[i] <= 109
    -109 <= target <= 109

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/4sum

    解题思路

    做过之前的三数之和,感觉这一道题就是在三数之和上面添加一层循环就可以了----先排序,最后两层双指针。但是提交的时候遇到一些问题了。

    错误代码一

    func fourSum(nums []int, target int) [][]int {
    
    	if len(nums) < 4 {
    		return nil
    	}
    	sort.Ints(nums)
    	result := make([][]int,0)
    	for i:=0;i<len(nums);i++{
            // 第一层循环
    		tmp := threeSum(nums[i],nums[i+1:],target-nums[i])
    		result = append(result,tmp...)
    	}
    	return result
    }
    
    
    func threeSum(val int,nums []int,target int) [][]int {
    
    	result := make([][]int,0)
    	for i:=0;i<len(nums);i++{
    		x,y := i+1,len(nums)-1
    		tmp := target - nums[i]
    		for x < y {
    			// 这里直接是为了去重
    			for x <= len(nums)-2 && nums[x] == nums[x+1]{
    				x++
    				continue
    			}
    			for y > x && nums[y] == nums[y-1] {
    				y--
    				continue
    			}
    			if nums[x] + nums[y] == tmp {
    				arr := []int{val,nums[i],nums[x],nums[y]}
    				result = append(result,arr)
    				x++
    				y--
    			}else if nums[x] + nums[y] > tmp {
    				y--
    			}else if nums[x] + nums[y] < tmp {
    				x++
    			}
    		}
    	}
    	return result
    }
    
    

    用例:nums := []int{2,2,2,2,2},target=8的时候出现错误,结果为:[[2 2 2 2] [2 2 2 2] [2 2 2 2]]。因为在第一层循环没有去重的情况下,即使后面上层去重了,也会导致出现重复的情况。于是想着给第一层添加当i>0的时候,如果此时的数等于上一个数则直接跳出本次循环。

    错误代码二

    func fourSum(nums []int, target int) [][]int {
    
    	if len(nums) < 4 {
    		return nil
    	}
    	sort.Ints(nums)
    	result := make([][]int,0)
    	for i:=0;i<len(nums);i++{
    		if i>0 && nums[i] == nums[i-1] {
    			continue
    		}
    		tmp := threeSum(nums[i],nums[i+1:],target-nums[i])
    		result = append(result,tmp...)
    	}
    	return result
    }
    
    
    func threeSum(val int,nums []int,target int) [][]int {
    
    	result := make([][]int,0)
    	for i:=0;i<len(nums);i++{
    		x,y := i+1,len(nums)-1
    		tmp := target - nums[i]
    		for x < y {
    			// 这里直接是为了去重
    			for x <= len(nums)-2 && nums[x] == nums[x+1]{
    				x++
    				continue
    			}
    			for y > x && nums[y] == nums[y-1] {
    				y--
    				continue
    			}
    			if nums[x] + nums[y] == tmp {
    				arr := []int{val,nums[i],nums[x],nums[y]}
    				result = append(result,arr)
    				x++
    				y--
    			}else if nums[x] + nums[y] > tmp {
    				y--
    			}else if nums[x] + nums[y] < tmp {
    				x++
    			}
    		}
    	}
    	return result
    }
    
    

    给第一层去重了之后,提交运行,还是同一个例子出现错误,结果为:[[2 2 2 2] [2 2 2 2]]。因为第一层已经去重了,出现问题只能是之后了。经过调试发现,在第二层这里,没有对本次遍历的值是否与上一次的相等进行判断。给第二层添加当i>0的时候,如果此时的数等于上一个数则直接跳出本次循环。,

    错误代码三

    func fourSum(nums []int, target int) [][]int {
    
    	if len(nums) < 4 {
    		return nil
    	}
    	sort.Ints(nums)
    	result := make([][]int,0)
    	for i:=0;i<len(nums);i++{
    		if i>0 && nums[i] == nums[i-1] {
    			continue
    		}
    		tmp := threeSum(nums[i],nums[i+1:],target-nums[i])
    		result = append(result,tmp...)
    	}
    	return result
    }
    
    
    func threeSum(val int,nums []int,target int) [][]int {
    
    	result := make([][]int,0)
    	for i:=0;i<len(nums);i++{
    		if i>0 && nums[i] == nums[i-1] {
    			continue
    		}
    		x,y := i+1,len(nums)-1
    		tmp := target - nums[i]
    		for x < y {
    			// 这里直接是为了去重
    			for x <= len(nums)-2 && nums[x] == nums[x+1]{
    				x++
    				continue
    			}
    			for y > x && nums[y] == nums[y-1] {
    				y--
    				continue
    			}
    			if nums[x] + nums[y] == tmp {
    				arr := []int{val,nums[i],nums[x],nums[y]}
    				result = append(result,arr)
    				x++
    				y--
    			}else if nums[x] + nums[y] > tmp {
    				y--
    			}else if nums[x] + nums[y] < tmp {
    				x++
    			}
    		}
    	}
    	return result
    }
    
    

    这次上面的例子通过,但是当nums=[]int{-2,-1,-1,1,1,2,2},target=0的时候,结果只为:[[-2 -1 1 2]]。与正确结果不符合,还有一个[-1,-1,1,1]。经过调试发现是因为第三层的判断出现了错误,因为y > x && nums[y] == nums[y-1],会导致x=y的情况而导致在判断-1,-1,1,1这个结果的时候直接跳出循环。因为是y-1会导致判断向前看,但是我们每一次的判断是向后看的,也就是我们需要看nums[y]不与nums[y+1]相等。

    正确代码

    上面的修改完之后,就正确咯

    func fourSum(nums []int, target int) [][]int {
    
    	if len(nums) < 4 {
    		return nil
    	}
    	sort.Ints(nums)
    	log.Println(nums)
    	result := make([][]int,0)
    	for i:=0;i<len(nums);i++{
    		if i>0 && nums[i] == nums[i-1] {
    			continue
    		}
    		tmp := threeSum(nums[i],nums[i+1:],target-nums[i])
    		result = append(result,tmp...)
    	}
    	return result
    }
    
    
    func threeSum(val int,nums []int,target int) [][]int {
    
    	result := make([][]int,0)
    	for i:=0;i<len(nums);i++{
    		if i>0 && nums[i] == nums[i-1] {
    			continue
    		}
    		x,y := i+1,len(nums)-1
    		tmp := target - nums[i]
    		for x < y {
    			// 这里的循环,都是为了让下一次的循环值等于上次的循环值
    			if x>i+1 && nums[x] == nums[x-1] {
    				x++
    				continue
    			}
    			if y>=0 && y<len(nums)-1 && nums[y] == nums[y+1] {
    				y--
    				continue
    			}
    
    			if nums[x] + nums[y] == tmp {
    				arr := []int{val,nums[i],nums[x],nums[y]}
    				result = append(result,arr)
    				x++
    				y--
    			}else if nums[x] + nums[y] > tmp {
    				y--
    			}else if nums[x] + nums[y] < tmp {
    				x++
    			}
    		}
    	}
    	return result
    }
    
  • 相关阅读:
    linux 短信收发
    sama5d3 环境检测 adc测试
    【Codeforces 723C】Polycarp at the Radio 贪心
    【Codeforces 723B】Text Document Analysis 模拟
    【USACO 2.2】Preface Numbering (找规律)
    【Codeforces 722C】Destroying Array (数据结构、set)
    【USACO 2.1】Hamming Codes
    【USACO 2.1】Healthy Holsteins
    【USACO 2.1】Sorting A Three-Valued Sequence
    【USACO 2.1】Ordered Fractions
  • 原文地址:https://www.cnblogs.com/MyUniverse/p/14892976.html
Copyright © 2011-2022 走看看