由于之前看了牛客网的数据结构和算法的课程知道了左神,现在找到了这本书当作入门书做做吧,虽然书的题解都是java实现的,但好在用c++实现难度不大。
第二章 链表问题
第一题:删除链表的中间节点和a/b处的节点
删除节点的题目我们之前已经讨论过,如果要删除一个节点,则需要找到待删除节点的前一个节点。
删除中间节点
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* removeLastKthNode(ListNode *head, int n) {
if (head == NULL || head->next == NULL)
{
return head;
}
if (head->next->next == NULL)
{
return head->next;
}
ListNode* pre = head;
ListNode* cur = head->next->next;
while (cur->next != NULL &&cur->next->next!=NULL) {
pre = pre->next;
cur = cur->next->next;
}
pre->next = pre->next->next;
return head;
}
删除a/b处节点
首先算出链表的长度n,再通过向上取整求得double r=((double)(a*n))/((double)b)的值即为要删除的节点。
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* removeLastKthNode(ListNode *head, int a,int b) {
if (a<1 || a>b) {
return head;
}
int n = 0;
ListNode* count = head;
while (count != NULL) {
count = count->next;
++n;
}
n = (int)ceil(((double)(a*n)) / ((double)b));
if (n == 1) {
return head->next;
}
if (n > 1) {
count = head;
while (n != 1) {
count = count->next;
--n;
}
count->next = count->next->next;
return head;
}
}
第二题:反转单向链表和双向链表
关键在while循环
反转单向链表
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode* removeLastKthNode(ListNode *head) {
if (head == NULL || head->next == NULL)return head;
ListNode* pre = NULL, *next = NULL;
while (head != NULL) {
next = head->next;
head->next = pre;
pre = head;
head = next;
}
return pre;
}
反转双向链表
关键还是在while循环里加了一句head->last = next;
struct DoubleListNode {
int val;
DoubleListNode *last;
DoubleListNode *next;
DoubleListNode(int x) : val(x), next(NULL) {}
};
DoubleListNode* removeLastKthNode(DoubleListNode *head) {
if (head == NULL || head->next == NULL)return head;
DoubleListNode* pre = NULL, *next = NULL;
while (head != NULL) {
next = head->next;
head->next = pre;
head->last = next;
pre = head;
head = next;
}
return pre;
}