Golang每日一练(leetDay0022)
Posted Hann Yang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang每日一练(leetDay0022)相关的知识,希望对你有一定的参考价值。
目录
64. 最小路径和 Minimum Path Sum
给定一个包含非负整数的 m x n
网格 grid
,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
说明:每次只能向下或者向右移动一步。
示例 1:
输入:grid = [[1,3,1],[1,5,1],[4,2,1]] 输出:7 解释:因为路径 1→3→1→1→1 的总和最小。
示例 2:
输入:grid = [[1,2,3],[4,5,6]] 输出:12
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 200
0 <= grid[i][j] <= 100
代码1:动态规划
package main
import (
"fmt"
)
func minPathSum(grid [][]int) int
m, n := len(grid), len(grid[0])
dp := make([][]int, m)
for i := range dp
dp[i] = make([]int, n)
dp[0][0] = grid[0][0]
for i := 1; i < m; i++
dp[i][0] = dp[i-1][0] + grid[i][0]
for j := 1; j < n; j++
dp[0][j] = dp[0][j-1] + grid[0][j]
for i := 1; i < m; i++
for j := 1; j < n; j++
dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j]
return dp[m-1][n-1]
func min(a, b int) int
if a < b
return a
return b
func main()
grid := [][]int1, 3, 1, 1, 5, 1, 4, 2, 1
fmt.Println(minPathSum(grid))
grid = [][]int1, 2, 3, 4, 5, 6
fmt.Println(minPathSum(grid))
输出:
7
12
代码2:DFS
package main
import (
"fmt"
)
func minPathSum(grid [][]int) int
m, n := len(grid), len(grid[0])
return dfs(grid, m-1, n-1)
func dfs(grid [][]int, i, j int) int
if i == 0 && j == 0
return grid[0][0]
res, left := 1<<31, 1<<31
if i > 0
res = dfs(grid, i-1, j)
if j > 0
left = dfs(grid, i, j-1)
if res > left
res = left
return res + grid[i][j]
func main()
grid := [][]int1, 3, 1, 1, 5, 1, 4, 2, 1
fmt.Println(minPathSum(grid))
grid = [][]int1, 2, 3, 4, 5, 6
fmt.Println(minPathSum(grid))
写成闭包函数:
package main
import (
"fmt"
)
func minPathSum(grid [][]int) int
var dfs func(i, j int) int
dfs = func(i, j int) int
if i == 0 && j == 0
return grid[0][0]
res, left := 1<<31, 1<<31
if i > 0
res = dfs(i-1, j)
if j > 0
left = dfs(i, j-1)
if res > left
res = left
return res + grid[i][j]
return dfs(len(grid)-1, len(grid[0])-1)
func main()
grid := [][]int1, 3, 1, 1, 5, 1, 4, 2, 1
fmt.Println(minPathSum(grid))
grid = [][]int1, 2, 3, 4, 5, 6
fmt.Println(minPathSum(grid))
65. 有效数字 Valid Number
有效数字(按顺序)可以分成以下几个部分:
- 一个 小数 或者 整数
- (可选)一个
'e'
或'E'
,后面跟着一个 整数
小数(按顺序)可以分成以下几个部分:
- (可选)一个符号字符(
'+'
或'-'
) - 下述格式之一:
- 至少一位数字,后面跟着一个点
'.'
- 至少一位数字,后面跟着一个点
'.'
,后面再跟着至少一位数字 - 一个点
'.'
,后面跟着至少一位数字
- 至少一位数字,后面跟着一个点
整数(按顺序)可以分成以下几个部分:
- (可选)一个符号字符(
'+'
或'-'
) - 至少一位数字
部分有效数字列举如下:["2", "0089", "-0.1", "+3.14", "4.", "-.9", "2e10", "-90E3", "3e+7", "+6e-1", "53.5e93", "-123.456e789"]
部分无效数字列举如下:["abc", "1a", "1e", "e3", "99e2.5", "--6", "-+3", "95a54e53"]
给你一个字符串 s
,如果 s
是一个 有效数字 ,请返回 true
。
示例 1:
输入:s = "0" 输出:true
示例 2:
输入:s = "e" 输出:false
示例 3:
输入:s = "." 输出:false
提示:
1 <= s.length <= 20
s
仅含英文字母(大写和小写),数字(0-9
),加号'+'
,减号'-'
,或者点'.'
。
代码:
package main
import (
"fmt"
"strings"
)
func isNumber(s string) bool
s = strings.TrimSpace(s)
if len(s) == 0
return false
hasNum := false
hasDot := false
hasE := false
for i, ch := range s
if ch >= '0' && ch <= '9'
hasNum = true
else if ch == '.'
if hasDot || hasE || i == len(s)-1 || (i == 0 && len(s) == 1)
return false
hasDot = true
else if ch == 'e' || ch == 'E'
if hasE || !hasNum || i == len(s)-1 || i == 0
return false
hasE = true
hasNum = false
else if ch == '+' || ch == '-'
if i != 0 && (s[i-1] != 'e' && s[i-1] != 'E')
return false
else
return false
return hasNum
func main()
fmt.Println(isNumber("0"))
fmt.Println(isNumber(" 0.1 "))
fmt.Println(isNumber("abc"))
fmt.Println(isNumber("1 a"))
fmt.Println(isNumber("2e10"))
fmt.Println(isNumber(" -90e3 "))
fmt.Println(isNumber(" 1e"))
fmt.Println(isNumber("e3"))
fmt.Println(isNumber(" 6e-1"))
fmt.Println(isNumber(" 99e2.5 "))
fmt.Println(isNumber("53.5e93"))
fmt.Println(isNumber(" --6 "))
fmt.Println(isNumber("-+3"))
fmt.Println(isNumber("95a54e53"))
输出:
true
true
false
false
true
true
false
false
true
false
true
false
false
false
代码2:
用正则表达式判断
package main
import (
"fmt"
"regexp"
)
func isNumber(s string) bool
pattern := "^\\\\s*([+-]?((\\\\d+\\\\.?)|(\\\\.\\\\d+)|(\\\\d+\\\\.\\\\d+)))((e|E)[+-]?\\\\d+)?\\\\s*$"
matched, _ := regexp.MatchString(pattern, s)
return matched
func main()
fmt.Println(isNumber("0"))
fmt.Println(isNumber(" 0.1 "))
fmt.Println(isNumber("abc"))
fmt.Println(isNumber("1 a"))
fmt.Println(isNumber("2e10"))
fmt.Println(isNumber(" -90e3 "))
fmt.Println(isNumber(" 1e"))
fmt.Println(isNumber("e3"))
fmt.Println(isNumber(" 6e-1"))
fmt.Println(isNumber(" 99e2.5 "))
fmt.Println(isNumber("53.5e93"))
fmt.Println(isNumber(" --6 "))
fmt.Println(isNumber("-+3"))
fmt.Println(isNumber("95a54e53"))
66. 加一 Plus One
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入:digits = [1,2,3] 输出:[1,2,4] 解释:输入数组表示数字 123。
示例 2:
输入:digits = [4,3,2,1] 输出:[4,3,2,2] 解释:输入数组表示数字 4321。
示例 3:
输入:digits = [0] 输出:[1]
提示:
1 <= digits.length <= 100
0 <= digits[i] <= 9
代码:
package main
import (
"fmt"
)
func plusOne(digits []int) []int
n := len(digits)
for i := n - 1; i >= 0; i--
if digits[i] < 9
digits[i]++
return digits
digits[i] = 0
return append([]int1, digits...)
func plusOne2(digits []int) []int
n := len(digits)
for i := n - 1; i >= 0; i--
if digits[i] < 9
digits[i]++
for j := i + 1; j < n; j++
digits[j] = 0
return digits
return append([]int1, make([]int, n)...)
func plusOne3(digits []int) []int
var carry int // 进位
n := len(digits)
digits[n-1]++
for i := n - 1; i >= 0; i--
digits[i] += carry
carry = digits[i] / 10
digits[i] %= 10
if carry > 0
digits = append([]int1, digits...)
return digits
func main()
digits := []int4, 3, 2, 1
fmt.Println(plusOne(digits))
digits2 := []int4, 3, 2, 1
fmt.Println(plusOne2(digits2))
digits3 := []int4, 3, 2, 1
fmt.Println(plusOne3(digits3))
输出:
[4 3 2 2]
[4 3 2 2]
[4 3 2 2]
🌟 每日一练刷题专栏 🌟
✨ 持续,努力奋斗做强刷题搬运工!
👍 点赞,你的认可是我坚持的动力!
🌟 收藏,你的青睐是我努力的方向!
✎ 评论,你的意见是我进步的财富!
☸ 主页:https://hannyang.blog.csdn.net/
![]() | Golang每日一练 专栏 |
![]() | Python每日一练 专栏 |
![]() | C/C++每日一练 专栏 |
![]() | Java每日一练 专栏 |
Golang每日一练(leetDay0028)
目录
82. 删除排序链表中的重复元素 II Remove-duplicates-from-sorted-list-II 🌟🌟
83. 删除排序链表中的重复元素 Remove-duplicates-from-sorted-list 🌟
84. 柱状图中最大的矩形 Largest-rectangle-in-histogram 🌟🌟🌟
82. 删除排序链表中的重复元素 II Remove-duplicates-from-sorted-list-II
给定一个已排序的链表的头 head
, 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。
示例 1:
输入:head = [1,2,3,3,4,4,5] 输出:[1,2,5]
示例 2:
输入:head = [1,1,1,2,3] 输出:[2,3]
提示:
- 链表中节点数目在范围
[0, 300]
内 -100 <= Node.val <= 100
- 题目数据保证链表已经按升序 排列
代码1:双指针
package main
import (
"fmt"
)
type ListNode struct
Val int
Next *ListNode
func removeDuplicates(head *ListNode) *ListNode
if head == nil || head.Next == nil
return head
dummy := &ListNodeVal: 0, Next: head
pre := dummy
cur := head
for cur != nil
if cur.Next != nil && cur.Val == cur.Next.Val
// 相同节点一直跳过
for cur.Next != nil && cur.Val == cur.Next.Val
cur = cur.Next
pre.Next = cur.Next
else
pre = pre.Next
cur = cur.Next
return dummy.Next
func build(list []int) *ListNode
head := &ListNodeVal: 0
for i := len(list) - 1; i >= 0; i--
p := &ListNodeVal: list[i]
p.Next = head.Next
head.Next = p
return head
func (head *ListNode) travel()
for p := head.Next; p != nil; p = p.Next
fmt.Print(p.Val)
if p.Next != nil
fmt.Print("->")
fmt.Println("<nil>")
func main()
head := build([]int1, 2, 3, 3, 4, 4, 5)
removeDuplicates(head).travel()
head = build([]int1, 1, 1, 2, 3)
removeDuplicates(head).travel()
输出:
1->2->5<nil>
2->3<nil>
代码2:递归法
package main
import (
"fmt"
)
type ListNode struct
Val int
Next *ListNode
func removeDuplicates(head *ListNode) *ListNode
if head == nil || head.Next == nil
return head
if head.Val == head.Next.Val
for head.Next != nil && head.Val == head.Next.Val
head = head.Next
return removeDuplicates(head.Next)
else
head.Next = removeDuplicates(head.Next)
return head
func build(list []int) *ListNode
head := &ListNodeVal: 0
for i := len(list) - 1; i >= 0; i--
p := &ListNodeVal: list[i]
p.Next = head.Next
head.Next = p
return head
func (head *ListNode) travel()
for p := head.Next; p != nil; p = p.Next
fmt.Print(p.Val)
if p.Next != nil
fmt.Print("->")
fmt.Println("<nil>")
func main()
head := build([]int1, 2, 3, 3, 4, 4, 5)
removeDuplicates(head).travel()
head = build([]int1, 1, 1, 2, 3)
removeDuplicates(head).travel()
83. 删除排序链表中的重复元素 Remove-duplicates-from-sorted-list
给定一个已排序的链表的头 head
, 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。
示例 1:
输入:head = [1,1,2] 输出:[1,2]
示例 2:
输入:head = [1,1,2,3,3] 输出:[1,2,3]
提示:
- 链表中节点数目在范围
[0, 300]
内 -100 <= Node.val <= 100
- 题目数据保证链表已经按升序 排列
代码1:双指针
package main
import (
"fmt"
)
type ListNode struct
Val int
Next *ListNode
func deleteDuplicates(head *ListNode) *ListNode
if head == nil || head.Next == nil
return head
pre := head
cur := head.Next
for cur != nil
if pre.Val == cur.Val
pre.Next = cur.Next
else
pre = cur
cur = cur.Next
return head
func build(list []int) *ListNode
head := &ListNodeVal: 0
for i := len(list) - 1; i >= 0; i--
p := &ListNodeVal: list[i]
p.Next = head.Next
head.Next = p
return head
func (head *ListNode) travel()
for p := head.Next; p != nil; p = p.Next
fmt.Print(p.Val)
if p.Next != nil
fmt.Print("->")
fmt.Println("<nil>")
func main()
head := build([]int1, 1, 2)
deleteDuplicates(head).travel()
head = build([]int1, 1, 2, 3, 3)
deleteDuplicates(head).travel()
双指针另一种写法:
func deleteDuplicates(head *ListNode) *ListNode
if head == nil
return nil
cur := head
for cur.Next != nil
if cur.Val == cur.Next.Val
cur.Next = cur.Next.Next
else
cur = cur.Next
return head
输出:
1->2<nil>
1->2->3<nil>
代码2:递归法
递归处理子链表,如果子链表的头节点和下一个节点的值相等,则将头节点的 next 指针指向下一个节点的下一个节点,这样就可以删除重复节点。
package main
import (
"fmt"
)
type ListNode struct
Val int
Next *ListNode
func deleteDuplicates(head *ListNode) *ListNode
if head == nil || head.Next == nil
return head
head.Next = deleteDuplicates(head.Next)
if head.Val == head.Next.Val
return head.Next
return head
func build(list []int) *ListNode
head := &ListNodeVal: 0
for i := len(list) - 1; i >= 0; i--
p := &ListNodeVal: list[i]
p.Next = head.Next
head.Next = p
return head
func (head *ListNode) travel()
for p := head.Next; p != nil; p = p.Next
fmt.Print(p.Val)
if p.Next != nil
fmt.Print("->")
fmt.Println("<nil>")
func main()
head := build([]int1, 1, 2)
deleteDuplicates(head).travel()
head = build([]int1, 1, 2, 3, 3)
deleteDuplicates(head).travel()
84. 柱状图中最大的矩形 Largest-rectangle-in-histogram
给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
求在该柱状图中,能够勾勒出来的矩形的最大面积。
示例 1:
输入:heights = [2,1,5,6,2,3] 输出:10 解释:最大的矩形为图中红色区域,面积为 10
示例 2:
输入: heights = [2,4] 输出: 4
提示:
1 <= heights.length <=10^5
0 <= heights[i] <= 10^4
代码1: 暴力枚举
package main
import "fmt"
func largestRectangleArea(heights []int) int
n := len(heights)
maxArea := 0
for i := 0; i < n; i++
left, right := i, i
for left >= 0 && heights[left] >= heights[i]
left--
for right < n && heights[right] >= heights[i]
right++
area := heights[i] * (right - left - 1)
if area > maxArea
maxArea = area
return maxArea
func main()
heights := []int2, 1, 5, 6, 2, 3
fmt.Println(largestRectangleArea(heights))
heights = []int2, 4
fmt.Println(largestRectangleArea(heights))
输出:
10
4
代码2: 单调栈
package main
import "fmt"
func largestRectangleArea(heights []int) int
n := len(heights)
stack := make([]int, 0)
maxArea := 0
for i := 0; i <= n; i++
var curHeight int
if i == n
curHeight = 0
else
curHeight = heights[i]
for len(stack) > 0 && curHeight < heights[stack[len(stack)-1]]
h := heights[stack[len(stack)-1]]
stack = stack[:len(stack)-1]
var w int
if len(stack) == 0
w = i
else
w = i - stack[len(stack)-1] - 1
area := h * w
if area > maxArea
maxArea = area
stack = append(stack, i)
return maxArea
func main()
heights := []int2, 1, 5, 6, 2, 3
fmt.Println(largestRectangleArea(heights))
heights = []int2, 4
fmt.Println(largestRectangleArea(heights))
代码3: 分治法
package main
import "fmt"
func largestRectangleArea(heights []int) int
return helper(heights, 0, len(heights)-1)
func helper(heights []int, left, right int) int
if left > right
return 0
minIndex := left
for i := left; i <= right; i++
if heights[i] < heights[minIndex]
minIndex = i
area1 := heights[minIndex] * (right - left + 1)
area2 := helper(heights, left, minIndex-1)
area3 := helper(heights, minIndex+1, right)
return max(area1, max(area2, area3))
func max(a, b int) int
if a > b
return a
return b
func main()
heights := []int2, 1, 5, 6, 2, 3
fmt.Println(largestRectangleArea(heights))
heights = []int2, 4
fmt.Println(largestRectangleArea(heights))
🌟 每日一练刷题专栏 🌟
✨ 持续,努力奋斗做强刷题搬运工!
👍 点赞,你的认可是我坚持的动力!
🌟 收藏,你的青睐是我努力的方向!
✎ 评论,你的意见是我进步的财富!
☸ 主页:https://hannyang.blog.csdn.net/
![]() | Golang每日一练 专栏 |
![]() | Python每日一练 专栏 |
![]() | C/C++每日一练 专栏 |
![]() | Java每日一练 专栏 |
以上是关于Golang每日一练(leetDay0022)的主要内容,如果未能解决你的问题,请参考以下文章