[LeetCode] 单向链表常用操作
LeetCode 中的单链表的结构定义一般是:
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
1. 找到链表中间节点
示意:
1 -> [2] -> 3 # 链表长度为奇数时,中间节点就是最中间的那个
1 -> [2] -> 3 -> 4 # 链表长度为偶数时,中间结点是「前一半链表」的尾巴
[] # 空链表返回空(NULL)
方法:使用快慢指针:
/* 传入链表的头 head,返回链表中间结点 */
ListNode* endOfFirstHalf(ListNode* head) {
ListNode* fast = head;
ListNode* slow = head;
while (fast->next && fast->next->next) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
2. 翻转链表
示意:
1 -> 2 -> 3 ==> 3 -> 2 -> 1
方法:
/* 传入旧链表的头 head,返回新链表的头 */
ListNode* reverseList(ListNode* head) {
ListNode* prev = nullptr;
ListNode* curr = head;
while (curr) {
ListNode* nextTemp = curr->next;
curr->next = prev;
prev = curr;
curr = nextTemp;
}
return prev;
}
可以预见,对一个链表翻转两次,就复原了:
list == reverseList(reverseList(list))
这个性质有时候非常有用,比如你需要翻转链表才能做一些事,但做完你要做的事以后,还应该把链表再翻转回去,因为最好不要修改原数据。
待更新