首页 > 其他分享 >代码随想录day7 | 454 四数相加|| 383 赎金信 15 三数之和 18 四数之和

代码随想录day7 | 454 四数相加|| 383 赎金信 15 三数之和 18 四数之和

时间:2024-07-23 15:20:54浏览次数:5  
标签:四数 15 nums int res 随想录 ++ right left

454 四个数相加==0

func fourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int) int {
	// 1. 用哈希表存储 nums1 和 nums2 两者之和的所有可能情况
	// 2. 遍历 nums3 和 nums4 两者之和的相反数,如果在哈希表中存在,则结果加上哈希表中的值
	// 3. 返回结果
	sum1 := make(map[int]int)
	for _, n1 := range nums1 {  // 将前两个数组之和存入map
		for _, n2 := range nums2 {
			sum1[n1+n2]++
		}
	}

	sum2 := make(map[int]int)
	for _, n3 := range nums3{
		for _, n4 := range nums4{
			sum2[n3+n4]++
		}
	}

	var res int
	for k1, v1 := range sum1{
		if v2, ok := sum2[-k1]; ok { // k1 + k2 == 0 ,即题设条件
			res += v1*v2  //  v1 个组合 * v2 个组合
		}
	}
	return res
}

时间n*n +n*n + 最坏n = n^2  空间 map存储两数之和的组合 n*n = n^2

383 赎金信(判断一个字符串是否完全包含另一个字符串)

func canConstruct(ransomNote string, magazine string) bool {
	// 思考 在一个集合里面寻找元素,优先考虑哈希表
	m := make(map[rune]int)
	for _, val := range magazine {
		m[val]++
	}

	for _, val2 := range ransomNote{
		if v, ok := m[val2]; ok && v>0 { // 如果每个字符都能在map中找到,那么最终true
			m[val2]-- // 改字符数量-1
			continue // 进入下一次循环
		}
		return false // 未进入商城条件判断,那么说明出现字符不在map,或者数量超过,那么返回false
	}
	return true
}
时间 m+n  空间n

15 三数之和

func threeSum(nums []int) [][]int {
	// hash算法太复杂,去重太麻烦,直接考虑双指针思路了
	var res [][]int
	nums = insert_sort(nums)
	fmt.Println(nums)
	for i := 0; i < len(nums) - 2; i++{ // 最终也要给left,right预留位置,所以最后要空出两个元素位置
		if nums[i] > 0 { // 如果排序后的首个元素>0 ,后面怎么加都会>0
			return res
		}

		if i > 0 && nums[i] == nums[i-1] { // 和之前遍历结果对比,如果相同,那么跳过本次循环
			continue
		}

		left , right := i + 1, len(nums) - 1
		sum := nums[i] + nums[left] + nums[right]
		for left < right { // !!!此处为什么不能写  sum != 0 && left < right ,因为这样一次循环最多只找到一个结果,但是可能有多个结果
			if sum > 0 { // 大于0说明要缩小,所以right左移
				right--
			}else if sum < 0 {
				left++
			}else {
				res = append(res, []int{nums[i], nums[left], nums[right]})
				// 针对左右指针去重
				left++
				for left < right && nums[left] == nums[left-1]{
					left++
				}
				right--
				for left < right && nums[right] == nums[right+1]{
					right--
				}
			}
			sum = nums[i] + nums[left] + nums[right]
		}
	}
	return res
}
// 总结,难点在于思路,以及对三个指针的去重操作,涉及到去重,所以优先考虑的hash表算法复杂度太高放弃了,然后考虑双指针方法,通过先排序然后遍历一次,之后内部双指针向中间移动,实现三指针元素之和==0,之后就是针对指针去重,去重原理就是用当前指针和之前的指针对比,这样相当于新的结果集和老的结果集对比,实现对结果集的去重


// 时间 插排n^2 + 遍历n*左右指针移动和n = n^2   空间 二维数组n^2

18 四数之和

func fourSum(nums []int, target int) [][]int {
	// 思路 三数之和外层再套一个for循环
	var res [][]int
	nums = quick_sort(nums)
	fmt.Println(nums)
	for i := 0; i < len(nums) - 3; i++ {
		if nums[i] > target && nums[i] > 0 { // 防止出现【-2,-1,0,1】 target = -3这种错误剪枝
			return res
		}
		if i > 0 && nums[i] == nums[i-1] { // 已经计算过同样的结果集,跳过
			continue
		}

		// 三数之和
		for j := i+1; j < len(nums) - 2; j++{
			if nums[i] + nums[j] > target && nums[i] + nums[j] > 0 {  // 剪枝,和大于0,说明nums【j】肯定>0, 此时往右两个元素也>0, 无论元素target是正数还是负数,都不可能缩小了,所以无需继续循环
				break  // 剪枝跳出当前循环
			}
			if j > i+1 && nums[j] == nums[j-1] {
				continue
			}

			left, right := j+1, len(nums)-1
			for left < right{
				sum := nums[i] + nums[j] + nums[left] + nums[right]
				if sum > target{
					right--
				}else if sum < target {
					left++
				}else {
					res = append(res, []int{nums[i], nums[j], nums[left], nums[right]})
					left++
					for left < right && nums[left] == nums[left-1]{
						left++
					}
					right--
					for left < right && nums[right] == nums[right+1]{
						right--
					}
				}
			}
		}

	}
	return res

}

func quick_sort(nums []int) []int {
	// 快速排序思想: 选择一个值,然后遍历列表,实现左边列表小于值, 右边大于值, 然后再对左右子列表快排
	if len(nums) <= 1 { // 递归终止条件
		return nums
	}

	// 为什么不能包含povid,如果包含,那么就是pivot被塞入左边或者右边的一个数组中,此时进入递归后,
	// 因为pivod在数组最左侧位置,并且右边元素或者都小于或者都大于pivod,此时就会陷入无限递归,每次都不会缩小问题规模
	pivot := nums[0]
	var left, right  []int
	for _, val := range nums[1:] {
		if val < pivot {
			left = append(left, val)
		} else {
			right = append(right, val)
		}
	}

	return append(append(quick_sort(left), pivot), quick_sort(right)...)
}

// 思考,本题主要在于边界条件以及剪枝的处理,何时return 何时break

时间 n^3  空间 n^2

标签:四数,15,nums,int,res,随想录,++,right,left
From: https://www.cnblogs.com/zhougongjin55/p/18318482

相关文章

  • 算法-代码随想录-哈希表
    有效的字母异位词思路:数组作为一个简单的哈希表,可以用来记录字符串中每个字符出现的次数。可以设置一个数组,第一轮遍历s中的字符,字符每出现一次,在数组对应位置+1。第二轮遍历t中的字符,字符每出现一次,在数组对应位置-1。最后遍历作为哈希表的数组,如果都为0,则说明每个字符出现的......
  • 出海收款平台有哪些?全球首要15种收付平台收费比较
    在跨境电商的浪潮中,收款问题一直是企业面临的最大挑战之一。随着全球化贸易的不断深入,越来越多的外国企业希望进入中国市场,但受限于法律法规和支付体系的不同,他们往往无法直接从中国用户手中收取款项。这时,第三方支付平台便显得尤为重要。今天,我们就来盘点一下全球首要的15种收......
  • 宠物电商平台小程序 毕业设计-附源码37159
                                    目 录摘要1绪论1.1研究背景1.2研究现状1.3springboot框架介绍2 宠物电商平台小程序系统分析2.1可行性分析2.2系统流程分析2.2.1数据流程3.3.2......
  • 「代码随想录算法训练营」第十八天 | 二叉树 part8
    669.修剪二叉搜索树题目链接:https://leetcode.cn/problems/trim-a-binary-search-tree/题目难度:中等文章讲解:https://programmercarl.com/0669.修剪二叉搜索树.html视频讲解:https://www.bilibili.com/video/BV17P41177ud?share_source=copy_web题目状态:没有思路,看题解过......
  • UAD155A0111 3BHE029110R0111 | 高速I/O模块
    型号:UAD155A01113BHE029110R0111品牌:ABB类别:高速I/O模块质保:一年输入电压范围:12-48VDC输出电压范围:5VDC。输出电流:最大10A。效率:大于90%。运行温度:-20°C至+50°C。存储温度:-40°C至+70°C。环境湿度:5%至95%相对湿度(无凝露)一、定义与功能定义:UAD15......
  • [COCI2015-2016#1] UZASTOPNI 题解
    前言题目链接:洛谷。题意简述一棵有根树,节点数\(n\leq10^5\),每个点有权值\(v_i\leq2000\),现在选出一些点,满足:一个点的父亲点若未被选择则其不能被选择。所选点的集合内不能有相同的权值。对于每一个选择的点,其子树中所有被选择点的权值必须可以构成公差为\(1\)的等......
  • CF1152C Neko does Maths
    欢迎您来我的网站看这篇题解!ProblemNekohastwointegers\(a\)and\(b\).Hisgoalistofindanon-negativeinteger\(k\)suchthattheleastcommonmultipleof\(a+k\)and\(b+k\)isthesmallestpossible.Iftherearemultipleoptimalintegers\(k\),h......
  • 【代码随想录训练营第42期 Day6打卡 LeetCode 242.有效的字母异位词 349.两个数组的交
    目录一、序言二、哈希表的相关知识1.基本概念2.常见的哈希结构3.总结三、题目及其题解242.有效的字母异位词题目链接题解思路1思路2思路3349.两个数组的交集题目链接题解202.快乐数题目链接题解1.两数之和题目链接题解思路1思路2四、小结一、序言......
  • 周报 | 24.7.15-24.7.21文章汇总
    为了更好地整理文章和发表接下来的文章,以后每周都汇总一份周报。Coggle数据科学|国产大模型速度评测(谁是更快大模型?)-CSDN博客周报|24.7.8-24.7.14文章汇总-CSDN博客计算机视觉研究院|CVPR:零样本通用分割框架(附源代码)-CSDN博客python|bashplotlib,一个有趣的Python库......
  • 代码随想录算法训练营第17天 | 复习二叉搜索树
    2024年7月19日题654.最大二叉树熟练运用递归即可classSolution{publicTreeNodeconstructMaximumBinaryTree(int[]nums){intmaxNum=Integer.MIN_VALUE;intflag=-1;for(inti=0;i<nums.length;i++){if(nums[i]>maxNum){......