2020.06.02 力扣 - 链表 - 0 两数相加

89 阅读1分钟

题目

给定一个链表,删除链表的倒数第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)

思考题

你能尝试使用一趟扫描实现吗?