题目
给定一个链表,删除链表的倒数第n个节点,并且返回链表的头结点。
示例
给定一个链表: 1->2->3->4->5, 和 n = 2.
当删除了倒数第二个节点后,链表变为 1->2->3->5.
给定的n保证是有效的。
代码提示
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func removeNthFromEnd(head *ListNode, n int) *ListNode {
}
思路
第一步:找到被移除的那个元素正向的下标
第二步:移除
代码
type ListNode struct {
Val int
Next *ListNode
}
func removeNthFromEnd(head *ListNode, n int) *ListNode {
if head == nil {
return nil
}
cnt := 0
// 算出总长度
lenHead := head
for lenHead != nil {
cnt++
lenHead = lenHead.Next
}
index := cnt - n
// 特殊值
if index < 0 || cnt == 1 {
return nil
}
if index == 0 {
return head.Next
}
// 正常情况
curr := head
add := 0
for curr != nil {
add++
if add == index {
curr.Next = curr.Next.Next
break
}
curr = curr.Next
}
return head
}
测试
func main() {
nums := []int{5, 4, 3, 2, 1}
var list1 *ListNode
for _, num := range nums {
list1 = addNode(list1, &ListNode{num, nil})
}
n := 2
ret := removeNthFromEnd(list1, n)
fmt.Println(ret)
nums = []int{2, 1}
var list2 *ListNode
for _, num := range nums {
list2 = addNode(list2, &ListNode{num, nil})
}
n = 2
ret = removeNthFromEnd(list2, n)
fmt.Println(ret)
}
func addNode(list, node *ListNode) *ListNode {
if list == nil {
return node
}
node.Next = list
return node
}
结果:
分析
时间复杂度:O(n)
空间复杂度:O(1)
思考题
你能尝试使用一趟扫描实现吗?