Golang每日一练(leetDay0028)

简介: Golang每日一练(leetDay0028)

82. 删除排序链表中的重复元素 II Remove-duplicates-from-sorted-list-II


给定一个已排序的链表的头 head删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表


示例 1:

be76b09759d3cec1b6f5d6737b8858eb.jpeg



输入:head = [1,2,3,3,4,4,5]

输出:[1,2,5]


示例 2:

1fbd6613f4364927a3fda6df6d664c97.jpeg

输入: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 := &ListNode{Val: 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 := &ListNode{Val: 0}
  for i := len(list) - 1; i >= 0; i-- {
    p := &ListNode{Val: 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([]int{1, 2, 3, 3, 4, 4, 5})
  removeDuplicates(head).travel()
  head = build([]int{1, 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 := &ListNode{Val: 0}
  for i := len(list) - 1; i >= 0; i-- {
    p := &ListNode{Val: 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([]int{1, 2, 3, 3, 4, 4, 5})
  removeDuplicates(head).travel()
  head = build([]int{1, 1, 1, 2, 3})
  removeDuplicates(head).travel()
}



83. 删除排序链表中的重复元素 Remove-duplicates-from-sorted-list


给定一个已排序的链表的头 head删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表

示例 1:

b7c1d37323c62498b2c6e22b768d055f.jpeg



输入:head = [1,1,2]

输出:[1,2]


示例 2:


a09b3323555f76257295eff950002c64.jpeg



输入: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 := &ListNode{Val: 0}
  for i := len(list) - 1; i >= 0; i-- {
    p := &ListNode{Val: 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([]int{1, 1, 2})
  deleteDuplicates(head).travel()
  head = build([]int{1, 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 := &ListNode{Val: 0}
  for i := len(list) - 1; i >= 0; i-- {
    p := &ListNode{Val: 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([]int{1, 1, 2})
  deleteDuplicates(head).travel()
  head = build([]int{1, 1, 2, 3, 3})
  deleteDuplicates(head).travel()
}




84. 柱状图中最大的矩形 Largest-rectangle-in-histogram


给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。


示例 1:

b7cd5928313ccf7cd1ae01aaa4d071b0.jpeg

输入:heights = [2,1,5,6,2,3]

输出:10

解释:最大的矩形为图中红色区域,面积为 10



示例 2:

311182329b8f8e0eb8f0068965fa68ba.jpeg

输入: 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 := []int{2, 1, 5, 6, 2, 3}
  fmt.Println(largestRectangleArea(heights))
  heights = []int{2, 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 := []int{2, 1, 5, 6, 2, 3}
  fmt.Println(largestRectangleArea(heights))
  heights = []int{2, 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 := []int{2, 1, 5, 6, 2, 3}
  fmt.Println(largestRectangleArea(heights))
  heights = []int{2, 4}
  fmt.Println(largestRectangleArea(heights))
}
目录
相关文章
|
Shell Linux 算法
Shell编程——弱数据类型的脚本语言快速入门指南
Shell编程——弱数据类型的脚本语言快速入门指南
182 0
Shell编程——弱数据类型的脚本语言快速入门指南
|
Go Linux Shell
Linux 终端命令之文件浏览(2) more
Linux 终端命令之文件浏览(2) more
136 0
Linux 终端命令之文件浏览(2) more
|
Shell 机器学习/深度学习 Linux
Linux 终端操作命令(2)内部命令
Linux 终端操作命令(2)内部命令
243 0
Linux 终端操作命令(2)内部命令
|
C++ 算法 存储
力扣 C++|一题多解之动态规划专题(2)
力扣 C++|一题多解之动态规划专题(2)
193 0
力扣 C++|一题多解之动态规划专题(2)
|
Python 索引
Python Numpy入门基础(一)创建数组
Python Numpy入门基础(一)创建数组
225 0
Python Numpy入门基础(一)创建数组
|
Java 容器 程序员
Java语言程序设计试卷6套
Java语言程序设计试卷6套
1120 0
Java语言程序设计试卷6套
|
Java Go C++
Golang每日一练(leetDay0120) 反转字符串中的元音字母、前K个高频元素
Golang每日一练(leetDay0120) 反转字符串中的元音字母、前K个高频元素
188 0
Golang每日一练(leetDay0120) 反转字符串中的元音字母、前K个高频元素
|
Go 机器学习/深度学习 Rust
Golang每日一练(leetDay0119) 反转字符串I\II Reverse String
Golang每日一练(leetDay0119) 反转字符串I\II Reverse String
279 0
Golang每日一练(leetDay0119) 反转字符串I\II Reverse String
|
16天前
|
存储 安全 Java
【Golang】(4)Go里面的指针如何?函数与方法怎么不一样?带你了解Go不同于其他高级语言的语法
结构体可以存储一组不同类型的数据,是一种符合类型。Go抛弃了类与继承,同时也抛弃了构造方法,刻意弱化了面向对象的功能,Go并非是一个传统OOP的语言,但是Go依旧有着OOP的影子,通过结构体和方法也可以模拟出一个类。
68 1
|
Go
Golang语言之管道channel快速入门篇
这篇文章是关于Go语言中管道(channel)的快速入门教程,涵盖了管道的基本使用、有缓冲和无缓冲管道的区别、管道的关闭、遍历、协程和管道的协同工作、单向通道的使用以及select多路复用的详细案例和解释。
522 4
Golang语言之管道channel快速入门篇

热门文章

最新文章

推荐镜像

更多