反转链表
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
来自:https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/
迭代法
从头到尾让当前节点指向当前节点的前一个节点,使用next指针标记当前节点本来的下一个节点。
C++
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==NULL){
return NULL;
}
ListNode *pre=NULL;
ListNode *cur=head;
ListNode *next=cur->next;
while(cur!=NULL){
next=cur->next;
cur->next=pre;
pre=cur;
cur=next;
}
return pre;
}
};
Go
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func reverseList(head *ListNode) *ListNode {
if head == nil {
return nil
}
var pre *ListNode
cur, next := head, head.Next
for cur != nil {
next = cur.Next
cur.Next = pre
pre = cur
cur = next
}
return pre
}
头插法
新定义一个指针作为返回结果的新链表的头结点,从头到尾遍历原链表的节点,一个一个头插如新链表,实现逆序。
C++
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head==NULL){
return NULL;
}
ListNode* ret=NULL;
ListNode* cur=head;
ListNode* next=cur->next;
while(cur!=NULL){
next=cur->next;
cur->next=ret;
ret=cur;
cur=next;
}
return ret;
}
};
Go
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
func reverseList(head *ListNode) *ListNode {
if head == nil {
return nil
}
var ret *ListNode
cur, next := head, head.Next
for cur != nil {
next = cur.Next
cur.Next = ret
ret = cur
cur = next
}
return ret
}
链表的回文结构
链接:https://www.nowcoder.com/questionTerminal/d281619e4b3e4a60a2cc66ea32855bfa
来源:牛客网
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
快慢指针->逆置后半段链表->字符串比较
C++
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:
bool chkPalindrome(ListNode* A) {
if(A==nullptr)
return true;
ListNode*head=A;
ListNode*fast=A;
ListNode* slow=A;
//1.快慢指针
while(fast!=nullptr&&fast->next!=nullptr){
slow=slow->next;
fast=fast->next->next;
}
//2.逆置后半段
ListNode*curNode=head;
ListNode*nextNode=head->next;
ListNode*preNode=nullptr;
while(curNode!=nullptr){
nextNode=curNode->next;
curNode->next=preNode;
preNode=curNode;
curNode=nextNode;
}
//3.前后半段字符比较
while(preNode!=nullptr&&head!=nullptr){
if(preNode->val!=head->val){
return false;
}
preNode=preNode->next;
head=head->next;
}
return true;
}
};
删除有序链表中重复的元素-II
链接:https://www.nowcoder.com/questionTerminal/71cef9f8b5564579bf7ed93fbe0b2024
来源:牛客网
给出一个升序排序的链表,删除链表中的所有重复出现的元素,只保留原链表中只出现一次的元素。
例如:
给出的链表为1→2→3→3→4→4→5, 返回1→2→5.
给出的链表为1→1→1→2→3, 返回2→3.
C++
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
/**
*
* @param head ListNode类
* @return ListNode类
*/
ListNode* deleteDuplicates(ListNode* head) {
if(head==nullptr)
return nullptr;
ListNode* pHead=head;
ListNode* pre=nullptr;
ListNode* start=head;
ListNode* end=head->next;
while(end!=nullptr){
if(start->val!=end->val){
pre=start;
start=end;
end=end->next;
}else{
while(end!=nullptr&&end->val==start->val){
end=end->next;
}
start=end;
if(pre!=nullptr){
pre->next=end;
}else{
pHead=start;
}
if(end!=nullptr)
end=end->next;
}
}
return pHead;
}
};
Go
package main
import . "nc_tools"
/*
* type ListNode struct{
* Val int
* Next *ListNode
* }
*/
/**
*
* @param head ListNode类
* @return ListNode类
*/
func deleteDuplicates(head *ListNode) *ListNode {
if head == nil {
return head
}
var pre *ListNode
pHead, start, end := head, head, head.Next
for end != nil {
if start.Val != end.Val {
pre = start
start = end
end = end.Next
} else {
for end != nil && end.Val == start.Val {
end = end.Next
}
start = end
if pre == nil {
pHead = start
} else {
pre.Next = end
}
if end != nil {
end = end.Next
}
}
}
return pHead
}
复杂链表的复制
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解答此题的关键在于,记录Random指针的指向。
/**
* Definition for a Node.
* type Node struct {
* Val int
* Next *Node
* Random *Node
* }
*/
func copyRandomList(head *Node) *Node {
if head == nil {
return nil
}
//1.复制链表
cur := head
for cur != nil {
newNode := &Node{Val: cur.Val}
oldNext := cur.Next
cur.Next = newNode
newNode.Next = oldNext
cur = oldNext
}
//2.置Random指针
cur = head
for cur != nil {
if cur.Next != nil {
if cur.Random != nil {
cur.Next.Random = cur.Random.Next
} else {
cur.Next.Random = nil
}
}
cur = cur.Next.Next
}
//3.拆分链表
cur, newHead, newCur := head, head.Next, head.Next
for cur != nil && newCur != nil {
curNext := cur.Next
newCurNext := newCur.Next
cur.Next = newCur.Next
if newCur.Next != nil {
newCur.Next = newCur.Next.Next
}
cur = curNext
newCur = newCurNext
}
return newHead
}