day03 移除链表元素、设计链表、反转链表

题目链接: 移除链表元素,设计链表, 反转链表
都是基础题目没有什么技巧

移除链表元素

Go

func removeElements(head *ListNode, val int) *ListNode {

	// 先处理头部(如果head.Val为目标值)
	for head != nil && head.Val == val {
		head = head.Next
	}
	if head == nil {
		return head
	}

	// 走到此处时,head肯定不是nil同时不是val,即头部不再需要处理

	// 双指针遍历链表
	prevNode, curNode := head, head.Next
	for curNode != nil {
		if curNode.Val == val {
			prevNode.Next = curNode.Next
		} else {
			prevNode = prevNode.Next
		}

		curNode = curNode.Next
	}
	return head
}

设计链表

Go

type ListNode struct {
	Val  int
	Next *ListNode
}

type MyLinkedList struct {
	head *ListNode // 头
	tail *ListNode // 尾
	size int
}

func Constructor() MyLinkedList {
	return MyLinkedList{
		head: &ListNode{},
		tail: nil,
		size: 0,
	}
}

// O(n)
func (l *MyLinkedList) Get(index int) int {
	if l.size == 0 || index >= l.size {
		return -1
	}

	curNode := l.head.Next
	for i := 0; i < index; i++ {
		curNode = curNode.Next
	}
	return curNode.Val
}

// O(1)
func (l *MyLinkedList) AddAtHead(val int) {
	newNode := &ListNode{Val: val}

	// 与head建立关系
	newNode.Next = l.head.Next
	l.head.Next = newNode

	// 判断tail此时是否为nil
	if l.tail == nil {
		// 说明当前值是插入的第一个节点
		l.tail = newNode
	}
	l.size++
}

// O(1)
func (l *MyLinkedList) AddAtTail(val int) {
	newNode := &ListNode{Val: val}
	// 判断tail是否为nil
	if l.tail == nil {
		// 说明当前值是插入的第一个节点
		l.head.Next = newNode
	} else {
		l.tail.Next = newNode
	}
	l.tail = newNode
	l.size++
}

// O(n)
func (l *MyLinkedList) AddAtIndex(index int, val int) {
	if index < 0 {
		return
	}
	if index > l.size {
		return
	}
	// index等于索引长度,则追加到链表末尾(这种情况涵盖的val为第一个节点的情况)
	if index == l.size {
		l.AddAtTail(val)
		return
	}

	preNode := l.head
	for i := 0; i < index; i++ {
		preNode = preNode.Next
	}

	// 当前prevNode即为当前要插入node的前一个节点
	newNode := &ListNode{Val: val}
	newNode.Next = preNode.Next
	preNode.Next = newNode

	l.size++
}

// O(n)
func (l *MyLinkedList) DeleteAtIndex(index int) {
	// index不存在直接返回
	if index < 0 || index >= l.size {
		return
	}

	// 走到这里说明,l.size为>=1的
	// 处理尾部
	preNode := l.head
	for i := 0; i < index; i++ {
		preNode = preNode.Next
	}

	preNode.Next = preNode.Next.Next

	if index == l.size-1 {
		l.tail = preNode
	}

	l.size--
}

反转链表

思路:
 nextNode=curNode.Next
 curNode.Next = prevNode
 prevNode=curNode
 curNode = nextNode

Go

func reverseList(head *ListNode) *ListNode {
	if head == nil || head.Next == nil {
		return head
	}

	prevNode, curNode := head, head.Next
	var nextNode *ListNode = nil
	for curNode != nil {
		nextNode = curNode.Next
		curNode.Next = prevNode
		prevNode = curNode
		curNode = nextNode
	}

	head.Next = nil
	return prevNode
}

你可能感兴趣的:(算法,算法)