【力扣日记】018 四数之和
题目描述:
给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。#答案中不能包括重复的元素
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/4sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
完全类似001两数之和 与015三数之和,在三数之和的基础上又加了一层循环。
class Solution:def fourSum(self, nums, target: int):nums.sort();print(nums)res = []j = 0for i in range(len(nums) - 3):if nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target:breakfor j in range(i + 1, len(nums)-2):l = j + 1r = len(nums) - 1while l < r:s = nums[i] + nums[j] + nums[l] + nums[r]if s == target:if [nums[i], nums[j], nums[l], nums[r]] not in res:res.append([nums[i], nums[j], nums[l], nums[r]])l += 1r -= 1while l < r and nums[l] == nums[l - 1]:l += 1while r > l and nums[r] == nums[r + 1]:r -= 1elif s > target:r -= 1else:l += 1return res
执行用时 :800 ms, 在所有 python3 提交中击败了59.48%的用户
代码鉴赏:
大佬优化版:
class Solution:def fourSum(self, nums: List[int], target: int) -> List[List[int]]:#排序+三数之和:a+b+c=-dln = len(nums)nums.sort()rnums = []for i in range(ln-3):#两个优化条件,当序列中最小的四个数之和>target时,序列后面没有符合条件的值if nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target:break#当序列当前值和最大的三个数之和<target,则当前值可以不找了,下一个值 continueif nums[i]+nums[ln-1]+nums[ln-2]+nums[ln-3]<target:continueif i >0 and nums[i]==nums[i-1]:continueStarget = target-nums[i]for j in range(i+1,ln-2):if nums[j]+nums[j+1]+nums[j+2]>Starget:breakif nums[j]+nums[ln-1]+nums[ln-2]<Starget:continueif j>i+1 and nums[j]==nums[j-1]:continueL = j + 1R = ln -1while(L<R):if nums[j]+nums[L]+nums[R]==Starget:rnums.append([nums[i],nums[j],nums[L],nums[R]])while (nums[L]==nums[L+1]) and L+1<ln-1:L+=1while (nums[R]==nums[R-1]) and R-1>j+1:R-=1L+=1R-=1elif nums[j]+nums[L]+nums[R]>Starget:R-=1else:L+=1return rnums
执行用时 :108 ms, 在所有 python3 提交中击败了92.79%的用户
大佬极端优化版:
class Solution:def fourSum(self, nums: List[int], target: int) -> List[List[int]]:# def fourSum(self, nums, target):dictNum2Count = {}listDiffNums = []listResult = []for value in nums:if value in dictNum2Count:dictNum2Count[value] += 1else:dictNum2Count[value] = 1listDiffNums.append(value)listDiffNums.sort()nLen = len(listDiffNums)if nLen < 1:return []if target < 4 * listDiffNums[0] or target > 4 * listDiffNums[nLen - 1]:return []# 四个相同的数if True:value1 = target / 4if value1 in dictNum2Count and dictNum2Count[value1] >= 4:listResult.append([value1, value1, value1, value1])# 三个相同的数for nIndex1 in range(nLen):value1 = listDiffNums[nIndex1]value1Count = dictNum2Count[value1]if value1Count >= 3:value2 = target - 3 * value1 if value2 in dictNum2Count and value2 != value1:if value1 > value2:listResult.append([value2, value1, value1, value1])else:listResult.append([value1, value1, value1, value2])# 其它情况:四个都不同;两个相同+两个不同;两个相同+两个相同dictTwoSum = {}minSum = 2 * listDiffNums[0]maxSum = 2 * listDiffNums[nLen-1]for nIndex1 in range(nLen):value1 = listDiffNums[nIndex1]value1Count = dictNum2Count[value1]if 2 * value1 + minSum > target:breakif value1 + listDiffNums[-1] + maxSum < target:continueif value1Count >= 2:sum = value1 + value1if sum not in dictTwoSum:dictTwoSum[sum] = [[nIndex1, nIndex1]]else:dictTwoSum[sum].append([nIndex1, nIndex1])for nIndex2 in range( nIndex1 + 1, nLen):value2 = listDiffNums[nIndex2]sum = value1 + value2if sum + minSum > target:breakif sum not in dictTwoSum:dictTwoSum[sum] = [[nIndex1, nIndex2]]else:dictTwoSum[sum].append([nIndex1, nIndex2])dictSumEdit = {}for twoSum, listlistIndex in dictTwoSum.items():leftSum = target - twoSumif twoSum in dictSumEdit or leftSum in dictSumEdit:continueelse:dictSumEdit[twoSum] = TruedictSumEdit[leftSum] = Trueif leftSum in dictTwoSum:leftListIndex = dictTwoSum[leftSum]for listIndex in listlistIndex:for leftIndex in leftListIndex:if listIndex[0] not in leftIndex and listIndex[1] not in leftIndex:result = sorted([listDiffNums[listIndex[0]], listDiffNums[listIndex[1]], listDiffNums[leftIndex[0]], listDiffNums[leftIndex[1]]])if result not in listResult:listResult.append(result)return list(listResult)
执行时间:大约70ms
【力扣日记】018 四数之和相关推荐
- 双指针解决力扣两/三数之和问题
双指针解决力扣两/三数之和问题 文章目录 双指针解决力扣两/三数之和问题 一.问题描述 二.分析 1.暴力 2.排序+双指针法 3.hash法 三.问题描述 四.分析 方法一:排序 + 双指针 五.代 ...
- 力扣(leetcode)-1. 两数之和
描述 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标. 你可以假设每种输入只会对应一个答案.但是,数组 ...
- 双指针算法(三):力扣【167.两数之和 | 经典例题
本文将讲述双指针算法的一个经典例题,167.两数之和 [题目描述] 给定一个已按照 升序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target . 函数应该以长 ...
- 力扣算法001_两数之和
1. 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,数组中同一个元素 ...
- 力扣题目——653. 两数之和 IV - 输入 BST
注:本文的实现思路主要是基于JS(JavaScript),涉及到的一些函数都是JS中的自带函数 题目描述 给定一个二叉搜索树 root 和一个目标结果 k,如果 BST 中存在两个元素且它们的和等于给 ...
- 力扣题目——1. 两数之和
注:本文的实现思路主要是基于JS(JavaScript),涉及到的一些函数都是JS中的自带函数 题目描述 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 t ...
- 力扣:15三数之和(python)
class Solution(object):def threeSum(self, nums):# 1.当nums的长度小于3的时候,直接返回[]if len(nums) < 3:return ...
- 力扣:1两数之和(python)-------->双向取值
题目:给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标. class Solution:def two ...
- 力扣-167题 两数之和 II - 输入有序数组(C++)- 双指针
题目链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/ 题目如下: class Solution {public ...
最新文章
- linux kvm虚拟化命令,Linux系统下kvm虚拟化(三)日常管理常用命令和配置说明
- 蚂蚁金服付志嵩:数据膨胀?关系复杂?如何升级图数据库?
- ActionScript 3 作用域内部细节介绍
- JavaScript getFullYear() 方法
- Vuex 源码还有一些缺陷?
- “蚂蚁牙黑”太火,想玩就用ModelArts做一个!
- Python爬虫辅助库BeautifulSoup4用法精要
- Spring Cloud中关于@EnableFeignClients注解的属性字段basePackages
- 关于数据分析的4点心得:维度、指标、KPI
- linux搭建博客-day 7安装Nginx
- ssm返回oracle序列,SSM之JSON通用返回格式
- 高德地图开放平台的使用
- Linux查看mpp数据库地址,linux下打开.mpp文件(微软project)._操作系统_rainysia的专栏-CSDN博客...
- 2019最新补单安全小技巧
- Unity3d FingerGestures
- LeetCode 对角线遍历(找规律)
- python提取excel指定关键词的行数据
- 医院洁净手术室设计装修要点SICOLAB
- layui表格table固定表头第一行固定显示
- VIAVI MTS-6000A新一代电信级以太网测试解决方案