code19: Remove Nth Node From End of List
Given a linked list, remove the n-th node from the end of list and return its head.
Example:
Given linked list: 1->2->3->4->5, and n = 2.
After removing the second node from the end, the linked list becomes 1->2->3->5.
Note:
Given n will always be valid.
Follow up:
Could you do this in one pass?
解答:
- 链表核心概念,遍历然后返回赋值原始链表的头部。
- 临界点:倒数第n个 边界:n=0以及输出链表为none时。
- 链表的遍历都是按照指针走向的,要删除倒数第n个点,就需要得到其长度。所以:
1 遍历一遍获取链表长度length
2 返回需要删除的位数number=length-n+1(删除第count个)
3 先行边界 在n<=length的情况下,else 则直接返回原链表
4 如果number = 1的话,需要删除第一个,但是我们一般在进行判断时,是判断next不为空而且count=number(count初始值为2,这样在删除第二个时,直接将第二个值跨越掉)。所以默认出现条件number=1时,直接返回res.next。
5 后面的按照触发相等条件时,替换next值操作,并返回res。未触发条件则coun+1,operation = operation.next
代码:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
if head == None or n == 0:
return head
else:
length = 0
res = head
operate_1 = head
while head !=None:
length +=1
head = head.next
if length <n:
return res
else:
number = length - n +1#[1,length]
if number == 1:
return res.next
else:#[2,length]
count = 2
while operate_1 != None and operate_1.next!=None:
if count == number:
operate_1.next = operate_1.next.next
return res
count +=1
operate_1 = operate_1.next
虽然时间复杂度也是O(n),但是还是有可以优化的地方:
- n超出了length范围时,可以不用单独列条件。转化思维:做number–,减到0时为临界点。
- 当删掉第一个时,也可以列入一般情况:我们新建链表节点时,将第一个点设置为0,这样我们遍历时是可以从该节点开始遍历的,next就会从第一个点开始了,最后结果返回res.next即可。
优化后的代码:
class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
if head == None or n == 0:
return head
else:
length = 0
res = ListNode(0)
res.next = head
operate_1 = head
while head !=None:
length +=1
head = head.next
#[1,len]
count = length - n #[-,length-1]
while count >=0:#[0,length-1]
if count == 0:
operate_1.next = operate_1.next.next
return res.next
count -=1
operate_1 = operate_1.next
return res.next