83. Remove Duplicates from Sorted List
Given a sorted linked list, delete all duplicates such that each element appear only once.
For example,
Given 1->1->2
, return 1->2
.
Given 1->1->2->3->3
, return 1->2->3
.
还是删除重复元素,只不过从数组变成了链表,但是感觉,反而更简单了?
判断只要等于下一个元素,就将该节点的next指向下一个节点的next
时间复杂度O(n),空间复杂度O(1)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (head == NULL) return head;
ListNode* ans = head;
while (head->next) {
if (head->val == head->next->val) {
head->next = head->next->next;
}
else head = head->next;
}
return ans;
}
};
82. Remove Duplicates from Sorted List II
Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.
For example,
Given 1->2->3->3->4->4->5
, return 1->2->5
.
Given 1->1->1->2->3
, return 2->3
.
记录一个cur表示当前链表走到哪里,pre表示上一个节点的位置。如果cur不停地在向后移动而pre不变,则在cur停止移动时,将pre->next设置为cur->next,表示删除所有相同元素;若是发现cur并未后移,那pre则和cur一同后移一步。时间复杂度O(n),空间复杂度O(1)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
if (!head) return NULL;
ListNode miao(0);
ListNode* ans = &miao;
ans->next = head;
ListNode* pre = ans;
ListNode* cur = head;
while (cur) {
while (cur->next && cur->val == cur->next->val)
cur = cur->next;
if (pre->next == cur)
pre = pre->next;
else
pre->next = cur->next;
cur = cur->next;
}
return ans->next;
}
};
203. Remove Linked List Elements
Remove all elements from a linked list of integers that have value val.
Example
Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6
Return: 1 --> 2 --> 3 --> 4 --> 5
看了看评论区,唔,居然我写的还算优雅的0 0
最近更喜欢写非递归,嗯
时间复杂度O(n),空间复杂度O(1)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
while (head && head->val == val) head = head->next;
if (!head) return head;
ListNode* cur = head;
while (head->next) {
if (head->next->val == val) head->next = head->next->next;
else head = head->next;
}
return cur;
}
};
19. Remove Nth Node From End of List
Given a linked list, remove the nth node from the end of list and return its head.
For 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.
Try to do this in one pass.
看评论区有种做法,设置两个指针,一个先向前走N+1步,再两个一起向前走,当第一个指针到达链表尾部时,正好是要删除的那个节点的上一个节点(至于为什么是N+1步,因为你要删除当前节点的话需要改变上一个节点的next)
时间复杂度都是O(n),空间复杂度也都是O(1)了,两种做法见仁见智吧
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) { //自己C++代码
if (!head) return head;
ListNode* cur = head;
int cnt = 0;
while (cur) {
cnt++;
cur = cur->next;
}
n = cnt - n;
cnt = 0;
if (n == 0) head = head->next;
cur = head;
while (cur) {
cnt++;
if (cnt == n) {
cur->next = cur->next->next;
break;
}
cur = cur->next;
}
return head;
}
};
public ListNode removeNthFromEnd(ListNode head, int n) { //评论区java代码
ListNode start = new ListNode(0);
ListNode slow = start, fast = start;
slow.next = head;
//Move fast in front so that the gap between slow and fast becomes n
for(int i=1; i<=n+1; i++) {
fast = fast.next;
}
//Move fast to the end, maintaining the gap
while(fast != null) {
slow = slow.next;
fast = fast.next;
}
//Skip the desired node
slow.next = slow.next.next;
return start.next;
}