Skip to content

Commit

Permalink
add leetcode
Browse files Browse the repository at this point in the history
  • Loading branch information
雷科伟 committed Feb 22, 2022
1 parent 3bd6973 commit 1f42616
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 148 deletions.
78 changes: 50 additions & 28 deletions leetcode/1/1.go
Original file line number Diff line number Diff line change
@@ -1,23 +1,11 @@
package main

// 单链表相关

type Node struct {
Val int
Next *Node
}

func NewNode(val int, next *Node) *Node {
return &Node{
Val: val,
Next: next,
}
}
import "go-demo/leetcode/common/list"

// 链表反转
func reverse(head *Node) *Node {
var prev *Node
var next *Node
func reverse(head *list.Node) *list.Node {
var prev *list.Node
var next *list.Node
for head != nil {
// 保存当前节点的下一个节点
next = head.Next
Expand All @@ -32,7 +20,7 @@ func reverse(head *Node) *Node {
}

// 链表反转-递归版
func reverse2(head *Node) *Node {
func reverse2(head *list.Node) *list.Node {
if head == nil || head.Next == nil {
return head
}
Expand All @@ -45,10 +33,10 @@ func reverse2(head *Node) *Node {
// 后驱节点
// 记录反转之前最后一个节点的后一个节点
// 帮助把反转之后的前N个节点能续上后续节点
var successor *Node
var successor *list.Node

// 反转链表前N个节点-递归版
func reverseN(head *Node, n int) *Node {
func reverseN(head *list.Node, n int) *list.Node {
if n == 1 {
successor = head.Next
return head
Expand All @@ -60,7 +48,7 @@ func reverseN(head *Node, n int) *Node {
}

// 链表倒数第k个节点
func findFromEnd(head *Node, k int) *Node {
func findFromEnd(head *list.Node, k int) *list.Node {
p1 := head
p2 := head

Expand All @@ -79,7 +67,7 @@ func findFromEnd(head *Node, k int) *Node {
}

// 单链表中点
func middleNode(head *Node) *Node {
func middleNode(head *list.Node) *list.Node {
p1 := head
p2 := head

Expand All @@ -93,7 +81,7 @@ func middleNode(head *Node) *Node {
}

// 判断链表是否是回文链表
func palindromes(head *Node) bool {
func palindromes(head *list.Node) bool {
// 因为链表没法从后往前遍历,所以我们可以先将链表反转一下
last := reverse(head)

Expand All @@ -109,15 +97,15 @@ func palindromes(head *Node) bool {

// 判断链表是否是回文链表
// 后续遍历法,树本质就是一个特殊的链表罢了
var left *Node
var left *list.Node

func isPalindromes(head *Node) bool {
func isPalindromes(head *list.Node) bool {
temp := *head
left = &temp
return palindromes2(head)
}

func palindromes2(right *Node) bool {
func palindromes2(right *list.Node) bool {
if right == nil {
return true
}
Expand All @@ -130,8 +118,8 @@ func palindromes2(right *Node) bool {
}

// 合并两个有序链表
func merge(l1 *Node, l2 *Node) *Node {
head := &Node{} // 虚拟头节点
func merge(l1 *list.Node, l2 *list.Node) *list.Node {
head := &list.Node{} // 虚拟头节点
pre := head
for l1 != nil && l2 != nil {
if l1.Val <= l2.Val {
Expand All @@ -152,7 +140,7 @@ func merge(l1 *Node, l2 *Node) *Node {
}

// 合并两个有序链表, 递归版
func merge2(l1 *Node, l2 *Node) *Node {
func merge2(l1 *list.Node, l2 *list.Node) *list.Node {
// 当l1为空时递归结束,直接将l2链接到Next上即可
if l1 == nil {
return l2
Expand All @@ -168,3 +156,37 @@ func merge2(l1 *Node, l2 *Node) *Node {
return l2
}
}

// 环形链表
// 判断该链表中是否存在环
// 只要一个元素出现两次,那么必定是有环的
func hasCycle(head *list.Node) bool {
exist := make(map[*list.Node]bool)
for head != nil {
if _, ok := exist[head]; ok {
return true
}
exist[head] = true
head = head.Next
}
return false
}

// 使用双指针,优化空间复杂度
func hasCycle2(head *list.Node) bool {
if head == nil || head.Next == nil {
return false
}

slow := head
quick := head.Next
for slow != quick {
if quick == nil || quick.Next == nil {
return false
}
// 快指针要比慢指针走快点
quick = quick.Next.Next
slow = slow.Next
}
return true
}
63 changes: 24 additions & 39 deletions leetcode/1/1_test.go
Original file line number Diff line number Diff line change
@@ -1,42 +1,17 @@
package main

import (
"go-demo/leetcode/common/list"
"testing"
)

// 1 -> 2 -> 3 -> 4 -> 5
func getHead() *Node {
node5 := NewNode(5, nil)
node4 := NewNode(4, node5)
node3 := NewNode(3, node4)
node2 := NewNode(2, node3)
node1 := NewNode(1, node2)
return node1
}

func getHead2() *Node {
node7 := NewNode(7, nil)
node6 := NewNode(6, node7)
node0 := NewNode(0, node6)
return node0
}

// 1 -> 2 -> 2 -> 1 -> nil
func getPalindromes() *Node {
node4 := NewNode(1, nil)
node3 := NewNode(2, node4)
node2 := NewNode(2, node3)
node1 := NewNode(1, node2)
return node1
}

func TestMain(m *testing.M) {
m.Run()
}

// 单链表反转
func TestReserve(t *testing.T) {
head := getHead()
head := list.GetHead()
newNode := reverse(head)

for newNode != nil {
Expand All @@ -47,7 +22,7 @@ func TestReserve(t *testing.T) {

// 单链表反转-递归
func TestReserve2(t *testing.T) {
head := getHead()
head := list.GetHead()
newNode := reverse2(head)

for newNode != nil {
Expand All @@ -58,7 +33,7 @@ func TestReserve2(t *testing.T) {

// 单链表反转前N个节点-递归
func TestReserveN(t *testing.T) {
head := getHead()
head := list.GetHead()
newNode := reverseN(head, 3)
for newNode != nil {
t.Log(newNode.Val)
Expand All @@ -68,30 +43,31 @@ func TestReserveN(t *testing.T) {

// 链表倒数第k个节点
func TestFindFromEnd(t *testing.T) {
head := getHead()
head := list.GetHead()
node := findFromEnd(head, 2)
t.Log(node.Val)
}

// 单链表中点
func TestMiddleNode(t *testing.T) {
head := getHead()
head := list.GetHead()
node := middleNode(head)
t.Log(node.Val)
}

// 链表是否是回文
func TestPalindromes(t *testing.T) {
t.Log(palindromes(getHead()))
t.Log(palindromes(getPalindromes()))
t.Log(palindromes(list.GetHead()))
t.Log(palindromes(list.GetPalindromes()))

t.Log(isPalindromes(getHead()))
t.Log(isPalindromes(getPalindromes()))
t.Log(isPalindromes(list.GetHead()))
t.Log(isPalindromes(list.GetPalindromes()))
}

// 合并有序链表
func TestMergeList(t *testing.T) {
l1 := getHead()
l2 := getHead2()
l1 := list.GetHead()
l2 := list.GetHead2()

l3 := merge(l1, l2)
for l3 != nil {
Expand All @@ -100,13 +76,22 @@ func TestMergeList(t *testing.T) {
}
}

// 合并有序链表,递归版
func TestMergeList2(t *testing.T) {
l1 := getHead()
l2 := getHead2()
l1 := list.GetHead()
l2 := list.GetHead2()

l3 := merge2(l1, l2)
for l3 != nil {
t.Log(l3.Val)
l3 = l3.Next
}
}

// 判断链表是否有环
func TestHasCircle(t *testing.T) {
t.Log(hasCycle(list.GetCycle()))

// 双指针法
t.Log(hasCycle2(list.GetCycle()))
}
58 changes: 0 additions & 58 deletions leetcode/11/11.go
Original file line number Diff line number Diff line change
@@ -1,63 +1,5 @@
package main

import "fmt"

// 环形链表
// 判断该链表中是否存在环

type Node struct {
Val int
Next *Node
}

func NewNode(val int, next *Node) *Node {
return &Node{
Val: val,
Next: next,
}
}

func main() {
node5 := NewNode(5, nil)
node4 := NewNode(4, node5)
node3 := NewNode(3, node4)
node2 := NewNode(2, node3)
node1 := NewNode(1, node2)

node5.Next = node3

fmt.Println(hasCycle(node1))
fmt.Println(hasCycle2(node1))
}

// 只要一个元素出现两次,那么必定是有环的
func hasCycle(head *Node) bool {
exist := make(map[*Node]bool)
for head != nil {
if _, ok := exist[head]; ok {
return true
}
exist[head] = true
head = head.Next
}
return false
}

// 使用双指针,优化空间复杂度
func hasCycle2(head *Node) bool {
if head == nil || head.Next == nil {
return false
}

slow := head
quick := head.Next
for slow != quick {
if quick == nil || quick.Next == nil {
return false
}
// 快指针要比慢指针走快点
quick = quick.Next.Next
slow = slow.Next
}
return true
}
3 changes: 2 additions & 1 deletion leetcode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@
- [三角形最大周长](17): 贪心算法
- [二叉树遍历](18): 前中后层序遍历
- [二叉树相关算法](19): 二叉树相关算法
- [二叉搜索树相关算法](20): BST(二叉搜索树)相关算法
- [二叉搜索树相关算法](20): BST(二叉搜索树)相关算法
- [表达式计算](21): 栈的使用
22 changes: 0 additions & 22 deletions leetcode/common/link/link.go

This file was deleted.

Loading

0 comments on commit 1f42616

Please sign in to comment.