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
    }
    
  • 相关阅读:
    ios获取iphone手机设备型号
    iOS项目中所有icon的尺寸以及命名
    c++达内视频
    ffmpeg教程
    FFMPEG SDK 教程
    minicom 下载
    线程同步的几种方法的总结
    多线程笔试面试概念问答
    buntu Rhythmbox解决中文乱码
    菜鸟学习ios
  • 原文地址:https://www.cnblogs.com/MyUniverse/p/14892976.html
Copyright © 2011-2022 走看看