1、总结
链表类问题都是in-place,空间复杂度都是O(1)的,在所有的排序算法中,时间复杂度为O(nlogn)的有三个:
1)快速排序(不开辟空间);
2)归并排序(需要开辟O(n)的空间,但是在list问题上不开辟空间);
3)堆排序(首先需要有一个堆)。
while里面写判断条件的时候规律:
如果接下来有head -> next,那么必须判断head是否为空,同理类推。
写链表的题目,一定要注意是否需要返回node,有些题目是void就是没有返回值的,自己经常没注意这个void就直接返回值了。
1.1、Remove Duplicates from Sorted List
https://leetcode.com/problems/remove-duplicates-from-sorted-list/#/description
存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除所有重复的元素,使每个元素 只出现一次 。
返回同样按升序排列的结果链表。
思路:使用一个node,相等的时候就node -> next = node -> next -> next,不相等的时候node往后移位.
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ func deleteDuplicates(head *ListNode) *ListNode { if head == nil { return head } dummy := head for dummy.Next != nil { if dummy.Val == dummy.Next.Val { dummy.Next = dummy.Next.Next } else { dummy = dummy.Next } } return head }
1.2、Remove Duplicates from Sorted List II
https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/#/description
存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字。
返回同样按升序排列的结果链表。
dummy node标准写法:
哨兵节点使用于头结点不确定的情况,题目中可能需要单独对头结点进行操作,这时候就可以引入哨兵节点。
dummy := &ListNode{
0,
head,
}
head = dummy
...
return dummy.next;
3)因为本题需要知道前驱节点,这样才能将所有重复的节点去掉,所以需要使用head->next和head->next->next。
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ func deleteDuplicates(head *ListNode) *ListNode { if head == nil || head.Next == nil { return head } dummy := &ListNode{ 0, head, } head = dummy for head.Next != nil && head.Next.Next != nil { if head.Next.Val == head.Next.Next.Val { flag := head.Next.Val for head.Next != nil && head.Next.Val == flag{ head.Next = head.Next.Next } } else { head = head.Next } } return dummy.Next }