链表中的节点每k个一组翻转
思路:采用递归的思想,每次处理k个节点,不足的就返回当前的节点头,层层递归得到每k个一翻转
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
/**
*
* @param head ListNode类
* @param k int整型
* @return ListNode类
*/
ListNode* reverseKGroup(ListNode* head, int k) {
// write code here
ListNode *tail = head;
for (int i = 0; i < k; i ++ ) {
if (tail) tail = tail -> next;
else return head;
}
ListNode *pre = nullptr, *cur = head, *next = nullptr;
while (cur != tail) {
next = cur -> next;
cur -> next = pre;
pre = cur;
cur = next;
}
head -> next = reverseKGroup(tail, k);
return pre;
}
};
链表中环的入口结点
思路:采用快慢指针的方法,快指针一次走两步,慢指针走一步,如果有环的话,两个指针一定会相遇,这时再将快指针置于头节点上,开始遍历,当两个指针相等时,就是入口节点(链接中有详细解释为什么要这样做,不懂的小伙伴可以看看)
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
*/
class Solution {
public:
ListNode* EntryNodeOfLoop(ListNode* pHead) {
if (pHead == NULL || pHead -> next == NULL) return NULL;
ListNode *slow = pHead, *fast = pHead;
while (fast && fast -> next) {
slow = slow -> next;
fast = fast -> next -> next;
if (slow == fast) break;
}
if (fast == NULL || fast -> next == NULL) return NULL;
fast = pHead;
while (fast != slow) {
fast = fast -> next;
slow = slow -> next;
}
return slow;
}
};
删除链表的倒数第n个节点
这题和上文中简单题的思路相同,我们同样可以采用快慢指针的方法,与简单题中不同的是我们需要一个前序节点来进行删除操作。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
/**
*
* @param head ListNode类
* @param n int整型
* @return ListNode类
*/
ListNode* removeNthFromEnd(ListNode* head, int n) {
// write code here
if (head == nullptr) return nullptr;
ListNode *all = new ListNode(-1);
all -> next = head;
ListNode *slow = head, *fast = head;
for (int i = 0; i < n; i ++ ) {
if (fast) fast = fast -> next;
else return nullptr;
}
ListNode *pre = all;
while (fast) {
pre = slow;
slow = slow -> next;
fast = fast -> next;
}
pre -> next = slow -> next;
return all -> next;
}
};
链表相加(二)
思路:我们所熟知的加法是从个位开始进行相加的,但是链表是单向的,且是从最高位开始的,由此我们可以先反转链表,最后进行相加
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
/**
*
* @param head1 ListNode类
* @param head2 ListNode类
* @return ListNode类
*/
ListNode* reverse(ListNode *head) {
if (head == nullptr) return nullptr;
ListNode *pre = nullptr, *cur = head, *next = nullptr;
while (cur) {
next = cur -> next;
cur -> next = pre;
pre = cur;
cur = next;
}
return pre;
}
ListNode* addInList(ListNode* head1, ListNode* head2) {
// write code here
if (head1 == nullptr) return head2;
if (head2 == nullptr) return head1;
head1 = reverse(head1);
head2 = reverse(head2);
ListNode *res = new ListNode(-1);
ListNode *head = res;
int carry = 0;
while (head1 || head2 || carry) {
int val1 = head1 ? head1 -> val : 0;
int val2 = head2 ? head2 -> val : 0;
int temp = val1 + val2 + carry;
carry = temp / 10;
temp = temp % 10;
head -> next = new ListNode(temp);
head = head -> next;
if (head1) head1 = head1 -> next;
if (head2) head2 = head2 -> next;
}
return reverse(res -> next);
}
};
单链表的排序
思路:取巧方法:遍历整个链表,存入一个vector,然后sort函数排序,再次存入。普通方法:采用分治的思想,先用快慢指针将链表分成一段一段地,再使用合并链表的方式合并(简单题里面有),下面开整
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
/**
*
* @param head ListNode类 the head node
* @return ListNode类
*/
ListNode* merge(ListNode* list1, ListNode* list2) {
if (list1 == nullptr) return list2;
if (list2 == nullptr) return list1;
ListNode* res = new ListNode(-1);
ListNode* head = res;
while (list1 || list2) {
int val1 = list1 ? list1 -> val : INT_MAX;
int val2 = list2 ? list2 -> val : INT_MAX;
if (val1 <= val2) {
head -> next = list1;
list1 = list1 -> next;
} else {
head -> next = list2;
list2 = list2 -> next;
}
head = head -> next;
}
return res -> next;
}
ListNode* sortInList(ListNode* head) {
// write code here
if (head == nullptr || head -> next == nullptr) return head;
ListNode *left = head, *mid = head -> next, *right = head -> next -> next;
while (right && right -> next) {
left = left -> next;
mid = mid -> next;
right = right -> next -> next;
}
left -> next = nullptr;
return merge(sortInList(head), sortInList(mid));
}
};
今天的算法题先写到这里,明天见朋友们(如果有人看的话)😍