YUANJI666 j4 FUN

Back

LeetCode Hot 100 刷题笔记 2(图论—技巧)Blur image

图论#

200.岛屿数量#

简单的dfs

994.腐烂的橘子#

这一题用广度优先遍历是很自然的,因为腐烂一次是影响四周的橘子

不过自己做得好吃力,关键在一些细节上

考虑 只有0,只有1,只有2的情况是否被考虑进去了

208.前缀树#

实现数据结构题

查找操作是很简单的,用哈希表就可以,但是前缀查找时间复杂度是很高的,要全部遍历一遍

使用前缀树,可以把前缀查找时间复杂度降为O(n)O(n)

回溯#

回溯算法的精髓在于回退操作

当我们从深层次的节点回到浅层次的节点时,通过撤销回到原来的状态

这就需要我们设计合适的状态变量

通过状态变量能精准地描述某种状态,通过修改状态变量能完美地回退到某个状态

==边递归边剪枝?==

46.全排列#

理解回溯经典的一道题

状态变量的设计:

  • 递归结束条件是递归深度,所以我们需要depth记录递归深度
  • 选过的数字不能再选,所以我们要记录已经选过的数字,即onPath变量

这一题中使用go语言解答要注意:

  • 答案添加的时候一定不能直接append path,因为切片是引用类型,每次更改都会改变原来的值,结果中每个切片结果会相等

78.子集#

求出所给数组的所有子集

状态变量的设计:

  • 在固定递归深度结束,维护depth
  • 每个结果的长度是不一样的,可以把set本身当作状态变量,撤销选只需要删除path中的末尾,撤销不选什么都不用做,depth已经说明了一切

17.电话号码#

这一题也是固定深度的递归,而且各层递归对字母的选择互不干扰,因此记录depth就行了

注意字符串和byte的转化,byte是uint8别名,能表示所有ascii码

N皇后#

一道固定深度的递归

斜方向的约束怎样设计需要想一想

二分#

153.寻找旋转排序数组的最小值#

经过思考,我发现了旋转排序数组与红蓝染色法的共性

红蓝染色最终根据target将数据分成两半

满足条件:蓝色的左边一定是蓝色,红色的右边一定是红色(数组有序

旋转数组仔细一想其实也是两段,且也满足上面的条件 只不过这里的蓝色是大于数组最后一个数的,红色是小于最后一个数的,所以他们的解答如此相似!

func findMin(nums []int) int {
	n := len(nums)
	l, r := -1, n
	for r - l > 1 {
		m := l + (r-l)/2
		if nums[m] <= nums[n-1] {
			r = m
		}else{
			l = m
		} 
	}
	return nums[r]   
}
go

33.搜索旋转排序数组#

  1. 两次二分:化归,通过153找到对应的段,然后正常查找
  2. 一次二分:每次移动LR的时候,加一个条件判断是否在同一递增段

技巧#

169.多数元素#