24. 两两交换链表中的节点
使用双指针,找到要交换的两个结点的前一个结点和该结点的前一个位置
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* pre = dummyHead;
ListNode* cur = head;
while (cur != nullptr && cur->next != nullptr) {
pre->next = cur->next;
cur->next = cur->next->next;
pre->next->next = cur;
cur = cur->next;
pre = pre->next->next;
}
return dummyHead->next;
}
};
19. 删除链表的倒数第 N 个结点
快慢指针
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* fast = dummyHead;
while (n--) {
fast = fast->next;
}
ListNode* slow = dummyHead;
while (fast->next != nullptr) {
fast = fast->next;
slow = slow->next;
}
ListNode* tmp = slow->next;
slow->next = slow->next->next;
delete tmp;
return dummyHead->next;
}
};
递归
class Solution {
public:
int cnt = 0;
ListNode* removeNthFromEnd(ListNode* head, int n) {
if(head == nullptr) return nullptr;
head->next = removeNthFromEnd(head->next, n);
cnt++;
if(cnt == n) return head->next;
return head;
}
};
面试题 02.07. 链表相交
先求两个链表长度,让长的移动长度的差值,然后再同时移动,若值相等则为交点。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* curA = headA;
ListNode* curB = headB;
int lenA = 0, lenB = 0;
while(curA != nullptr){
curA = curA->next;
lenA++;
}
while(curB != nullptr){
curB = curB->next;
lenB++;
}
curA = headA;
curB = headB;
if(lenB > lenA){
swap(lenA, lenB);
swap(curA, curB);
}
int gap = lenA - lenB;
while(gap--){
curA = curA->next;
}
while(curA != nullptr){
if(curA == curB) return curA;
curA = curA->next;
curB = curB->next;
}
return nullptr;
}
};
142. 环形链表 II
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
while(fast != nullptr && fast->next != nullptr){
slow = slow->next;
fast = fast->next->next;
if(slow == fast){
ListNode* slow = head;
while(slow != fast){
slow = slow->next;
fast = fast->next;
}
return slow;
}
}
return nullptr;
}
};
1616. 分割两个字符串得到回文串
a的前缀和b的后缀构成回文串,则从a左端往右和b右端往左,要有尽可能多的字符相等,当遇到不相等的字符后,索引i到索引j之间的字符串需要构成回文串(a或b都可以),这样拼接后总体是回文串。
class Solution {
bool isPalindrome(string &s, int i, int j) {
while (i < j && s[i] == s[j]) {
++i;
--j;
}
return i >= j;
}
bool check(string &a, string &b) {
int i = 0, j = a.length() - 1; // 相向双指针
while (i < j && a[i] == b[j]) { // 前后缀尽量匹配
++i;
--j;
}
return isPalindrome(a, i, j) || isPalindrome(b, i, j);
}
public:
bool checkPalindromeFormation(string a, string b) {
return check(a, b) || check(b, a);
}
};