1. 两数相加
两数相加(尾插法)
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode *head = nullptr, *tail = nullptr;
int carry = 0;
while (l1 || l2) {
int n1 = l1 ? l1->val: 0;//有值取值、没值赋0
int n2 = l2 ? l2->val: 0;
int sum = n1 + n2 + carry;//当前位和
if (!head) {
head = tail = new ListNode(sum % 10);//头指针初始化
} else {
tail->next = new ListNode(sum % 10);
tail = tail->next;
}
carry = sum / 10;
if (l1) {
l1 = l1->next;
}
if (l2) {
l2 = l2->next;
}
}
if(carry) tail->next = new ListNode(carry);
return head;
}
};
2. 删除链表的倒数第N位
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
//删除倒数第n个节点,前一节点要指向倒数n+1
ListNode* p1 =head;
ListNode* p2 =head;
for(int i=0;i<n;i++) p2=p2->next;
if(!p2) return head->next;//对于第一个点被删除的处理,也可以设一个头结点统一所有操作
while(p2->next){
p1=p1->next;
p2=p2->next;
}
p1->next=p1->next->next;
return head;
}
};
2. 合并两个有序链表
//合并k个可以采用二分合并、顺序合并
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* preHead = new ListNode(-1);
//一定要使用头指针并复制一个副本,不然后面循环操作不统一,未合并完的也不好加上去
ListNode* prev = preHead;
while (l1&&l2) {
if (l1->val < l2->val) {
prev->next = l1;//链入pre
l1 = l1->next;//指针后移
} else {
prev->next = l2;
l2 = l2->next;
}
prev = prev->next;//pre指针后移
}
// 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
prev->next = l1 == nullptr ? l2 : l1;
return preHead->next;
}
//也可以使用递归
};
3. 反转链表
//递归(从后往前进行尾插)
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (!head || !head->next)
return head;//返回初始为空的节点以及单个节点
ListNode* newHead = reverseList(head->next);
head->next->next = head;//head->next变成了尾结点,将head放在尾结点后
head->next = nullptr;
return newHead;
}
};
//头插法
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode*pre= new ListNode();
ListNode*node= head;
while(head!=NULL){
head=head->next;
node->next=pre->next;
pre->next=node;
node = head;
}
return pre->next;
}
};
5. 判断回文链表(递归)
//另一种做法快慢指针,再反转链表
public:
bool recursivelyCheck(ListNode* currentNode) {
if (currentNode != nullptr) {
if (!recursivelyCheck(currentNode->next)) //递归到最右,同时承接返回判断
return false;
if (currentNode->val != frontPointer->val) //从右往左出递归,如果不等返回假
return false;
frontPointer = frontPointer->next;//全局指针右移
}
return true;
}
bool isPalindrome(ListNode* head) {
frontPointer = head;
return recursivelyCheck(head);
}
};
6. 相交链表
//跑到终点后互换位置,要么最后相交、要么都为NULL
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if (headA == nullptr || headB == nullptr) {
return nullptr;
}
ListNode *pA = headA, *pB = headB;
while (pA != pB) {
pA = pA == nullptr ? headB : pA->next;
pB = pB == nullptr ? headA : pB->next;
}
return pA;
}
};