数组/字符串
1768.交替合并字符串
给你两个字符串 word1 和 word2 。请你从 word1 开始,通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长,就将多出来的字母追加到合并后字符串的末尾。
https://leetcode.cn/problems/merge-strings-alternately/description/?envType=study-plan-v2&envId=leetcode-75
func mergeAlternately(word1 string, word2 string) string {
var ans string
len1, len2 := len(word1), len(word2)
for i := 0; i < len1 || i < len2; i++ {
if i < len1 {
ans += string(word1[i])
}
if i < len2 {
ans += string(word2[i])
}
}
return ans
}
1071.字符串的最大公因子
对于字符串 s 和 t,只有在 s = t + t + t + ... + t + t(t 自身连接 1 次或多次)时,我们才认定 “t 能除尽 s”。
给定两个字符串 str1 和 str2 。返回 最长字符串 x,要求满足 x 能除尽 str1 且 x 能除尽 str2 。
https://leetcode.cn/problems/greatest-common-divisor-of-strings/description/?envType=study-plan-v2&envId=leetcode-75
func check(str string, strTemp string) bool{
repeat := len(str) / len(strTemp)
res := strings.Repeat(strTemp, repeat)
if strings.Compare(str, res)==0{
return true
}else{
return false
}
}
func gcdOfStrings(str1 string, str2 string) string {
len1, len2 := len(str1), len(str2)
for i:=int(math.Min(float64(len1), float64(len2))); i>=1; i--{
if len1%i==0 && len2%i==0{
strTemp := str1[0:i]
if check(str1, strTemp) && check(str2, strTemp){
return strTemp
}
}
}
return ""
}
1431.拥有最多糖果的孩子
给你一个数组 candies 和一个整数 extraCandies ,其中 candies[i] 代表第 i 个孩子拥有的糖果数目。
对每一个孩子,检查是否存在一种方案,将额外的 extraCandies 个糖果分配给孩子们之后,此孩子有 最多 的糖果。注意,允许有多个孩子同时拥有 最多 的糖果数目。
https://leetcode.cn/problems/kids-with-the-greatest-number-of-candies/description/?envType=study-plan-v2&envId=leetcode-75
解题思路:先遍历一次找到最大值,然后再遍历一次,对于每个数加上糖果数能不能达到最大值
func kidsWithCandies(candies []int, extraCandies int) []bool {
var maxx int = -1
for _, val := range candies{
if val > maxx{
maxx = val
}
}
var ans []bool
for _, val := range candies{
if val+extraCandies>=maxx{
ans = append(ans, true)
}else{
ans = append(ans, false)
}
}
return ans
}
605.种花问题
假设有一个很长的花坛,一部分地块种植了花,另一部分却没有。可是,花不能种植在相邻的地块上,它们会争夺水源,两者都会死去。
给你一个整数数组
flowerbed表示花坛,由若干0和1组成,其中0表示没种植花,1表示种植了花。另有一个数n,能否在不打破种植规则的情况下种入n朵花?能则返回true,不能则返回false。
https://leetcode.cn/problems/can-place-flowers/description/?envType=study-plan-v2&envId=leetcode-75
解题思路:直接遍历
func canPlaceFlowers(flowerbed []int, n int) bool {
placeCount := 0
if len(flowerbed) == 1{
if flowerbed[0]==0{
placeCount +=1
}
if placeCount < n{
return false
}else{
return true
}
}
for i:=0; i<len(flowerbed); i++{
if flowerbed[i]==0{
if i==0 && i+1<len(flowerbed){
if flowerbed[i+1]==0{
placeCount += 1
flowerbed[i]=1
}
}else if i==len(flowerbed)-1 && i-1>=0{
if flowerbed[i-1]==0{
placeCount += 1
flowerbed[i]=1
}
}else if flowerbed[i-1]==0 && flowerbed[i+1]==0{
placeCount += 1
flowerbed[i]=1
}
}
}
if placeCount < n{
return false
}else{
return true
}
}
345.反转字符串中的元音字母
给你一个字符串
s,仅反转字符串中的所有元音字母,并返回结果字符串。元音字母包括
'a'、'e'、'i'、'o'、'u',且可能以大小写两种形式出现不止一次。
https://leetcode.cn/problems/reverse-vowels-of-a-string/description/?envType=study-plan-v2&envId=leetcode-75
解题思路:双指针交换
func check(ch byte) bool {
chList := []byte{'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'}
for idx := range chList {
if ch == chList[idx] {
return true
}
}
return false
}
func reverseVowels(s string) string {
byteArr := make([]byte, len(s))
copy(byteArr[:], s)
//fmt.Println(byteArr)
l, r := 0, len(s)-1
for l < r {
for l < len(s) && check(byteArr[l]) == false {
l++
}
for r >= 0 && check(byteArr[r]) == false {
r--
}
if l >= r {
break
}
byteArr[l], byteArr[r] = byteArr[r], byteArr[l]
l++
r--
}
return string(byteArr)
}
151.反转字符串中的单词
func reverseWords(s string) string {
var ans string
var strList []string
s = strings.Trim(s, " ")
var temp []byte
for i := 0; i < len(s); i++ {
if s[i] != ' ' {
temp = append(temp, s[i])
} else {
if len(temp)!=0{
strList = append(strList, string(temp))
}
temp = []byte{}
}
}
strList = append(strList, string(temp))
for i := len(strList) - 1; i >= 0; i-- {
ans = ans + strList[i]
if i != 0 {
ans += " "
}
}
return ans
}
238.除自身以外数组的乘积
func productExceptSelf(nums []int) []int {
length := len(nums)
L, R, ans := make([]int, length), make([]int, length), make([]int, length)
L[0]=1
for i:=1; i<length; i++{
L[i] = L[i-1]*nums[i-1]
}
R[length-1]=1
for i:=length-2; i>=0; i--{
R[i] = R[i+1]*nums[i+1]
}
for i:=0; i<length; i++{
ans[i] = L[i]*R[i]
}
return ans
}
栈
2390.从字符串中移除星号
func removeStars(s string) string {
var stack []byte
for i:=0; i<len(s); i++{
if s[i]=='*'{
stack = stack[:len(stack)-1]
}else{
stack = append(stack, s[i])
}
}
return string(stack)
}
735.小行星碰撞
func asteroidCollision(asteroids []int) []int {
var stack []int
for i := 0; i < len(asteroids); i++ {
if len(stack) == 0 {
stack = append(stack, asteroids[i])
} else {
if check(stack[len(stack)-1], asteroids[i]) == 1 {
stack = append(stack, asteroids[i])
} else {
flag := 0
for len(stack) != 0 && check(stack[len(stack)-1], asteroids[i]) == 0 {
flag = 0
if getabs(stack[len(stack)-1]) > getabs(asteroids[i]) {
break
} else if getabs(stack[len(stack)-1]) == getabs(asteroids[i]) {
stack = stack[:len(stack)-1]
break
} else {
stack = stack[:len(stack)-1]
flag = 1
}
}
if flag == 1 {
stack = append(stack, asteroids[i])
}
}
}
}
return stack
}
func getabs(x int) int {
if x < 0 {
return -x
} else {
return x
}
}
func check(x, y int) int {
if x > 0 && y < 0 {
return 0
} else {
return 1
}
}
394.字符串解码
题目描述
给定一个经过编码的字符串,返回它解码后的字符串。
编码规则为:
k[encoded_string],表示其中方括号内部的encoded_string正好重复k次。注意k保证为正整数。你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。
此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数
k,例如不会出现像3a或2[4]的输入。
思路:栈模拟,数字单独作为一个元素,其他的[和单个字符单独作为一个元素
func decodeString(s string) string {
stack := []string{}
pos := 0
for pos < len(s){
cur := s[pos]
if cur >='0' && cur <='9'{
//数字存入
digits := getDigitsString(s, &pos)
stack = append(stack, digits)
}else if (cur>='a'&&cur<='z' || cur>='A'&&cur<='Z') || cur=='['{
//[xxx存入
stack = append(stack, string(cur))
pos++
}else{
//遇到]
pos++
substr := []string{}
for stack[len(stack)-1] != "[" {
substr = append(substr, stack[len(stack)-1])
stack = stack[:len(stack)-1] //pop
}
//反转
for i:=0; i<len(substr)/2; i++{
substr[i], substr[len(substr)-1-i] = substr[len(substr)-1-i], substr[i]
}
stack = stack[:len(stack)-1]
repTime, _ := strconv.Atoi(stack[len(stack)-1])
stack = stack[:len(stack)-1]
t := strings.Repeat(getString(substr), repTime)
stack = append(stack, t)
}
}
return getString(stack)
}
func getDigitsString(s string, pos *int) string {
var ret string = ""
for ; s[*pos] >='0' && s[*pos] <='9'; *pos++{
ret += string(s[*pos])
}
return ret
}
func getString(v []string) string{
var ret string = ""
for _, s := range v{
ret += s
}
return ret
}
队列
933.最近的请求次数
type RecentCounter struct {
arr []int
}
func Constructor() RecentCounter {
r := RecentCounter{}
return r
}
func (this *RecentCounter) Ping(t int) int {
this.arr = append(this.arr, t)
t1 := t-3000
count := 0
for i:=0; i<len(this.arr); i++{
if this.arr[i]>t{
break
}
if this.arr[i]>=t1{
count++
}
}
return count
}
649.Dota2参议院
解题思路:贪心+队列
使用两个队列 radiant 和 dire 分别按照投票顺序存储天辉方和夜魇方每一名议员的投票时间。
func predictPartyVictory(senate string) string {
var radiant, dire []int
for i, s := range senate{
if s == 'R'{
radiant = append(radiant, i)
}else{
dire = append(dire, i)
}
}
for len(radiant) >0 && len(dire)>0{
if radiant[0] < dire[0]{
dire = dire[1:]
radiant = append(radiant, radiant[0]+len(senate))
radiant = radiant[1:]
}else{
radiant = radiant[1:]
dire = append(dire, dire[0]+len(senate))
dire = dire[1:]
}
}
if len(radiant)>0{
return "Radiant"
}else{
return "Dire"
}
}
双指针
283.移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
双指针,一个指向数组前半部分最后一个0的下一位,另一个遍历数组
func moveZeroes(nums []int) {
if len(nums)==0{
return
}
zeroPtr := 0
for i:=0; i<len(nums); i++{
if nums[i]!=0{
nums[zeroPtr] = nums[i]
zeroPtr++
}
}
for j:=zeroPtr; j<len(nums); j++{
nums[j]=0
}
}
392.判断子序列
https://leetcode.cn/problems/is-subsequence/description/?envType=study-plan-v2&envId=leetcode-75
给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。
注意这个子序列不是传统意义上的子序列
func isSubsequence(s string, t string) bool {
if len(s) == 0{
return true
}
sPtr := 0
for j := 0; j<len(t); j++{
if s[sPtr] == t[j]{
sPtr++
}
if sPtr == len(s){
return true
}
}
return false
}
11.盛最多水的容器
双指针,从宽度最长开始,每次向内缩小时缩小的长度固定,所以肯定要缩小高度小的那个柱子
func maxArea(height []int) int {
res := 0
l := 0
r := len(height) - 1
for l < r {
curWidth := getmin(height[l], height[r])
curArea := curWidth * (r-l)
if curArea > res{
res = curArea
}
if height[l] < height[r]{
l ++
}else{
r --
}
}
return res
}
func getmin(a int, b int) int{
if a < b{
return a
}else{
return b
}
}
1679.K和数对的最大数目
func maxOperations(nums []int, k int) int {
sort.Ints(nums)
count := 0
left, right := 0, len(nums)-1
for left < right {
if nums[left]+nums[right] == k {
count++
left++
right--
}else if nums[left]+nums[right]>k{
right--
}else{
left++
}
}
return count
}
滑动窗口
643.子数组最大平均数I
func findMaxAverage(nums []int, k int) float64 {
curSum := 0
maxSum := 0
for i:=0; i<k; i++{
curSum += nums[i]
}
if len(nums)==k{
return float64(curSum)/float64(k)
}
maxSum = curSum
for i:=k; i<len(nums); i++{
curSum = curSum - nums[i-k] + nums[i]
if curSum > maxSum{
maxSum = curSum
}
}
return float64(maxSum)/float64(k)
}
1456.定长子串中元音的最大数目
func maxVowels(s string, k int) int {
curSum := 0
maxSum := 0
for i:=0; i<k; i++{
if isVolwel(s[i]){
curSum += 1
}
}
if len(s)==k{
return curSum
}
maxSum = curSum
for i:=k; i<len(s); i++{
if isVolwel(s[i-k]){
curSum--
}
if isVolwel(s[i]){
curSum++
}
if curSum > maxSum{
maxSum = curSum
}
}
return maxSum
}
func isVolwel(ch byte) bool{
volwel := []byte{'a', 'e', 'i', 'o', 'u'}
for i:=0; i<len(volwel); i++{
if ch ==volwel[i]{
return true
}
}
return false
}
1004.最大连续1的个数III
解题思路:要让1的长度最长,两端必定是0变成1;问题转换成0的个数小于等于k的前提下,窗口长度最长
func longestOnes(nums []int, k int) int {
left, cnt0 := 0, 0
ans :=0
for right, x := range nums{
if x==0{
cnt0++
}
for cnt0>k{
if nums[left]==0{
cnt0--
}
left++
}
if right-left+1 > ans{
ans = right-left+1
}
}
return ans
}
1493.删掉一个元素以后全为1的最长子数组
变长滑动窗口,解法同上一题1004.最大连续1的个数III
func longestSubarray(nums []int) int {
left, cnt := 0, 0
ans := 0
for right := range nums{
if nums[right]!=1{
cnt++
}
for cnt>1{
if nums[left]!=1{
cnt--
}
left++
}
if right-left+1 > ans{
ans = right-left+1
}
}
return ans-1
}
哈希表/哈希集合
2215.找出两数组的不同
func findDifference(nums1 []int, nums2 []int) [][]int {
var nums1Map =make(map[int]int, len(nums1))
var nums2Map =make(map[int]int, len(nums2))
for _, v := range nums1{
nums1Map[v] = 1
}
for _, v := range nums2{
nums2Map[v] = 1
}
var ans1, ans2 []int
for k := range nums1Map{
if _, ok := nums2Map[k]; !ok{
ans1 = append(ans1, k)
}
}
for k := range nums2Map{
if _, ok := nums1Map[k]; !ok{
ans2 = append(ans2, k)
}
}
return [][]int{ans1, ans2}
}
1207.独一无二的出现次数
一个map保存数和出现的次数,另一个map保存出现的次数和出现的次数的次数
func uniqueOccurrences(arr []int) bool {
arrMap := make(map[int]int, len(arr))
for i:=0; i<len(arr); i++{
arrMap[arr[i]]++
}
cntMap := make(map[int]int, len(arr))
for _, v := range arrMap{
cntMap[v]++
if cntMap[v]>=2{
return false
}
}
return true
}
1657.确定两个字符串是否接近
func closeStrings(word1 string, word2 string) bool {
count1, count2 := make([]int, 26), make([]int, 26)
for _, c := range word1 {
count1[c - 'a']++
}
for _, c := range word2 {
count2[c - 'a']++
}
for i := 0; i < 26; i++ {
if count1[i] > 0 && count2[i] == 0 || count1[i] == 0 && count2[i] > 0 {
return false
}
}
sort.Ints(count1)
sort.Ints(count2)
return reflect.DeepEqual(count1, count2)
}
func main() {
a := &[]int{1, 2, 3}
b := &[]int{1, 2, 3}
fmt.Println(reflect.DeepEqual(a, b), a == b, a, b) //true false &[1 2 3] &[1 2 3]
}
2352.相等行列对
func equalPairs(grid [][]int) int {
n := len(grid)
cnt := make(map[string]int)
for _, cow := range grid{
cnt[fmt.Sprint(cow)]++
}
ans := 0
for j:=0; j<n; j++{
var arr []int
for i:=0; i<n; i++{
arr = append(arr, grid[i][j])
}
if val, ok := cnt[fmt.Sprint(arr)]; ok{
ans += val
}
}
return ans
}
前缀和
1732.找到最高海拔
func largestAltitude(gain []int) int {
maxHeight := 0
curSum := 0
for i:=0; i<len(gain); i++{
curSum += gain[i]
if curSum > maxHeight{
maxHeight = curSum
}
}
return maxHeight
}
724.寻找数组的中心下标
func pivotIndex(nums []int) int {
sum := 0
for i:=0; i<len(nums); i++{
sum += nums[i]
}
pos := -1
curSum := 0
for i:=0; i<len(nums); i++{
rightSum := sum - curSum - nums[i]
if rightSum == curSum{
return i
}
curSum += nums[i]
}
return pos
}
二分查找
374.猜数字大小
func guessNumber(n int) int {
left, right := 1, n
for left <= right {
mid := left + (right-left)/2
if guess(mid)==0{
return mid
}else if guess(mid)==-1{
right = mid-1
}else {
left = mid+1
}
}
return left
}
163.寻找峰值
https://leetcode.cn/problems/find-peak-element/description/
题目描述
峰值元素是指其值严格大于左右相邻值的元素。
给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞ 。
你必须实现时间复杂度为 O(log n) 的算法来解决此问题。
//模板3
func findPeakElement(nums []int) int {
left, right := 0, len(nums)-1
for left+1 < right{
mid := left + (right-left)/2
if nums[mid-1] < nums[mid]{
left = mid
}else{
right = mid
}
}
if nums[left] > nums[right]{
return left
}else{
return right
}
}
2300.咒语和药水的成功对数
func successfulPairs(spells []int, potions []int, success int64) []int {
sort.Ints(potions)
ans := make([]int, len(spells))
for i:=0; i<len(spells); i++{
potionsLen := len(potions)
left, right := 0, potionsLen-1
var pos int = potionsLen
for left <= right{
mid := left + (right-left)/2
if check(spells[i], potions[mid], success){
pos = mid
right = mid-1
}else{
left = mid+1
}
}
ans[i] = potionsLen - pos
}
return ans
}
func check(spell int, potion int, success int64) bool{
if int64(spell) * int64(potion) >= success{
return true
}else{
return false
}
}
func successfulPairs(spells []int, potions []int, success int64) []int {
sort.Ints(potions)
ans := make([]int, len(spells))
for i:=0; i<len(spells); i++{
ans[i] = len(potions) - sort.SearchInts(potions, (int(success) - 1) / spells[i] + 1)
}
return ans
}
位运算
338.比特位计数
给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。
https://leetcode.cn/problems/counting-bits/description/?envType=study-plan-v2&envId=leetcode-75
最低设置位表示为一个正整数x的二进制表示中,最低的1所在的位,比如10的二进制表示1010,最低设置位为2
令y=x&(x-1),那么y就会将x的最低设置位之前的所有二进制位不变,把最低设置位的1变成0,显然y是小于x的。另外既然最低设置为从1变成了0,那么bits[y]=bits[x]-1,将y替换之后就是bits[x]=bits[x&(x-1)]+1
func countBits(n int) []int {
bits := make([]int, n+1)
bits[0]=0
for i:=1; i<=n; i++{
bits[i] = bits[i&(i-1)] + 1
}
return bits
}
136.只出现一次的数字
给你一个 **非空** 整数数组 `nums` ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
https://leetcode.cn/problems/single-number/description/?envType=study-plan-v2&envId=leetcode-75
性质a^b^b^c^c=a
func singleNumber(nums []int) int {
var ans = nums[0]
for i:=1; i<len(nums); i++{
ans ^= nums[i]
}
return ans
}
动态规划-一维
1137.第N个泰波那契数
func tribonacci(n int) int {
arr := make([]int, 38)
arr[0], arr[1], arr[2] = 0, 1, 1
for i:=3; i<=n; i++{
arr[i] = arr[i-1]+arr[i-2]+arr[i-3]
}
return arr[n]
}
746.使用最小花费爬楼梯
dp[i]表示达到下标i的最小花费
dp[i]=min(dp[i−1]+cost[i−1],dp[i−2]+cost[i−2])
func minCostClimbingStairs(cost []int) int {
dp := make([]int, len(cost)+1)
dp[0], dp[1] = 0, 0
for i:=2; i<=len(cost); i++{
dp[i] = dp[i-1] + cost[i-1]
if dp[i] > dp[i-2] + cost[i-2]{
dp[i] = dp[i-2] + cost[i-2]
}
}
return dp[len(cost)]
}
二叉搜素树
700.二叉搜索树中的搜索
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func searchBST(root *TreeNode, val int) *TreeNode {
if root == nil{
return root
}
if val == root.Val{
return root
}else if val < root.Val {
return searchBST(root.Left, val)
}else {
return searchBST(root.Right, val)
}
}
图-深度优先搜索
841.钥匙和房间
func canVisitAllRooms(rooms [][]int) bool {
var canIn = make([]int, len(rooms))
var keys = make([]int, len(rooms))
keys = append(keys, 0)
dfs(rooms, &canIn, &keys)
for i:= range canIn{
if canIn[i]==0{
return false
}
}
return true
}
func dfs(rooms [][]int, canIn *[]int, keys *[]int){
for _, key := range *keys{
if (*canIn)[key]==0{
(*canIn)[key]=1
(*keys) = (*keys)[1:]
(*keys) = append((*keys), rooms[key]...)
dfs(rooms, canIn, keys)
}
}
}
547.省份数量
func findCircleNum(isConnected [][]int) int {
n := len(isConnected)
pre := make([]int, n)
for i:=0; i<n; i++{
pre[i]=i
}
var find func(x int)int
find = func(x int) int{
if pre[x]==x{
return pre[x]
}else{
pre[x] = find(pre[x])
return pre[x]
}
}
join := func(a, b int){
fa := find(a)
fb := find(b)
if fa!=fb{
pre[fb] = fa
}
}
for i, row := range isConnected{
for j := i+1; j<n; j++{
if row[j]==1{
join(i, j)
}
}
}
ans := 0
for i := range pre{
if find(i)==i{
ans +=1
}
}
return ans
}
1926.迷宫中离入口最近的出口
func nearestExit(maze [][]byte, entrance []int) int {
n, m := len(maze), len(maze[0])
var next [][]int = [][]int{{1, 0}, {0, -1}, {0, 1}, {-1, 0}}
type node struct{
i, j, step int
}
q := []node{}
q = append(q, node{i:entrance[0], j:entrance[1], step:0})
maze[q[0].i][q[0].j] = '+'
for len(q)>0{
head := q[0]
q = q[1:]
for k:=0; k<4; k++{
tx := head.i + next[k][0]
ty := head.j + next[k][1]
if tx<0 || tx>=n || ty<0 || ty>=m || maze[tx][ty]=='+'{
continue
}
maze[tx][ty]='+'
if tx==n-1 || tx==0 || ty==m-1 || ty==0{
return head.step+1
}
q = append(q, node{i:tx, j:ty, step:head.step+1})
}
}
return -1
}
二叉树-广度优先搜索
199.二叉树的右视图
func rightSideView(root *TreeNode) []int {
res := [][]int{}
ans := []int{}
if root==nil{
return ans
}
queue := []*TreeNode{}
queue = append(queue, root)
var tempArr []int
for len(queue)>0{
length := len(queue)
for i:=0; i<length; i++{
node := queue[0]
queue = queue[1:]
tempArr = append(tempArr, node.Val)
if node.Left!=nil{
queue = append(queue, node.Left)
}
if node.Right!=nil{
queue = append(queue, node.Right)
}
}
res = append(res, tempArr)
ans = append(ans, tempArr[len(tempArr)-1])
tempArr = []int{}
}
fmt.Println(res)
return ans
}
二叉树-深度优先搜索
104.二叉树的最大深度
https://leetcode.cn/problems/maximum-depth-of-binary-tree/?envType=study-plan-v2&envId=leetcode-75
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func maxDepth(root *TreeNode) int {
if root == nil{
return 0
}
leftDepth := maxDepth(root.Left)
rightDepth := maxDepth(root.Right)
curMaxDepth := int(math.Max(float64(leftDepth), float64(rightDepth)))
return curMaxDepth+1
}
872.叶子相似的树
func leafSimilar(root1 *TreeNode, root2 *TreeNode) bool {
arr1, arr2 := make([]int, 0), make([]int, 0)
dfs(root1, &arr1)
dfs(root2, &arr2)
//fmt.Println(arr1, arr2)
return reflect.DeepEqual(arr1, arr2)
}
func dfs(root *TreeNode, arr *[]int){
if root == nil{
return
}
if root.Left==nil && root.Right==nil{
*arr = append(*arr, root.Val)
}
dfs(root.Left, arr)
dfs(root.Right, arr)
}
1448.统计二叉树中好节点的数目
func goodNodes(root *TreeNode) int {
maxVal := math.MinInt
ans := 0
dfs(root, maxVal, &ans)
return ans
}
func dfs(root *TreeNode, maxVal int, ans *int){
if root==nil{
return
}
if root.Val >= maxVal{
*ans += 1
maxVal = root.Val
//fmt.Printf("%d, %d\n", root.Val, ans)
}
dfs(root.Left, maxVal, ans)
dfs(root.Right, maxVal, ans)
}
437.路径总和 III
解题思路:dfs2是每个节点的值都要加上,这样就变成了先以根节点为准进行深搜,然后再以两个儿子节点为树的根进行搜索
func pathSum(root *TreeNode, targetSum int) int {
if root==nil{
return 0
}
ans := 0
dfs1(root, &ans, targetSum)
return ans
}
func dfs1 (node *TreeNode, ans *int, targetSum int){
if node==nil{
return
}
dfs2(node, 0, ans, targetSum)
dfs1(node.Left, ans, targetSum)
dfs1(node.Right, ans, targetSum)
}
func dfs2(node *TreeNode, curSum int, ans *int, targetSum int){
if node==nil{
return
}
curSum += node.Val
if curSum==targetSum{
*ans++
}
dfs2(node.Left, curSum, ans, targetSum)
dfs2(node.Right, curSum, ans, targetSum)
}
单调栈
739.每日温度
单调递减栈,存的是数组的下标
func dailyTemperatures(temperatures []int) []int {
length := len(temperatures)
stack := make([]int, 0) //stack表示的temperature中递减的数的下标
ans := make([]int, length)
for i:=0; i<length; i++{
for len(stack)>0 && temperatures[i]>temperatures[stack[len(stack)-1]]{
prevIndex := stack[len(stack)-1]
stack = stack[:len(stack)-1]
ans[prevIndex] = i-prevIndex
}
stack = append(stack, i)
}
return ans
}
链表
2095.删除链表的中间节点
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func deleteMiddle(head *ListNode) *ListNode {
ansHead := &ListNode{Next:head}
slow, fast := ansHead, ansHead
for fast.Next!=nil && fast.Next.Next!=nil{
slow = slow.Next
fast = fast.Next.Next
}
slow.Next = slow.Next.Next
return ansHead.Next
}
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func deleteMiddle(head *ListNode) *ListNode {
if head==nil{
return head
}else if head.Next==nil{
return nil
}
workHead := &ListNode{Next:head}
count := 0
for workHead.Next != nil{
count++
workHead = workHead.Next
}
count /= 2
workHead = &ListNode{Next:head}
for i:=0; i<count; i++{
workHead = workHead.Next
}
workHead.Next = workHead.Next.Next
return head
}
206.反转链表
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reverseList(head *ListNode) *ListNode {
var prev *ListNode
curPtr := head
for curPtr != nil{
next := curPtr.Next
curPtr.Next = prev
prev = curPtr
curPtr = next
}
return prev
}
328.奇偶链表
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func oddEvenList(head *ListNode) *ListNode {
if head==nil{
return head
}
oushuHead := head.Next
jishuPtr := head
oushuPtr := oushuHead
for oushuPtr!=nil && oushuPtr.Next!=nil{
jishuPtr.Next = oushuPtr.Next
jishuPtr = jishuPtr.Next
oushuPtr.Next = jishuPtr.Next
oushuPtr = oushuPtr.Next
}
jishuPtr.Next = oushuHead
return head
}