LeetCode记录2020.1.31
文章目录
109 有序链表转二叉搜索树(mid)
本题链表为升序,即相应二叉搜索树中序遍历后的结果,因此可将链表中点作为树或子树的根节点,然后利用左右两个被分割处的子链表范围递归构建左右子树。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* sortedListToBST(ListNode* head) {
return fromList2Bst(head, NULL);
}
TreeNode* fromList2Bst(ListNode* beg, ListNode* End){
if(beg==End)
return NULL;
ListNode *mid=beg, *fast=beg;
while(fast->next!=End&&fast->next->next!=End)
{
fast=fast->next->next;
mid=mid->next;
}
TreeNode* node = new TreeNode(mid->val);
node->left = fromList2Bst(beg, mid);
node->right = fromList2Bst(mid->next, End);
return node;
}
24 两两交换链表中的节点(mid)
迭代解法,注意指针的更新
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* header = new ListNode(-1);
header->next = head;
ListNode* pre = header;
while(pre!=NULL&&pre->next!=NULL&&pre->next->next!=NULL)
{
ListNode* first = pre->next;
ListNode* second = first->next;
ListNode* next = second->next;
second->next = first;
first->next = next;
pre->next = second;
pre = first;
}
return header->next;
}
};
148 排序链表(mid)
注意这道题除了要求时间复杂度为O(nlogn)外,还要求空间复杂度为常数级,因此不能用递归而要用迭代实现归并排序。链表可通过改变next成员实现原址归并。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* sortList(ListNode* head) {
int cnt = 1;
int total =0;
ListNode* dummyH = new ListNode(-1);
dummyH->next = head;
ListNode* End = dummyH;
while(End->next!=NULL)
{
End=End->next;
++total;
}
while(cnt<total)
{
ListNode* header = dummyH;
while(header->next!=NULL)
{
ListNode* nextHead = cut(header->next, cnt);
ListNode* nextnextHead = cut(nextHead, cnt);
header = merge(header->next, nextHead, header);
header->next = nextnextHead;
}
cnt*=2;
}
return dummyH->next;
}
ListNode* cut(ListNode* head, int cnt)
{
while(--cnt&&head!=NULL)
{
head=head->next;
}
ListNode* nextHead = head==NULL?NULL:head->next;
if(head!=NULL)
head->next = NULL;
return nextHead;
}
ListNode* merge(ListNode* a, ListNode* b, ListNode* preHead)
{
while(a!=NULL&&b!=NULL)
{
if(a->val<b->val)
{
preHead->next = a;
a=a->next;
}
else
{
preHead->next=b;
b=b->next;
}
preHead = preHead->next;
}
if(a==NULL)
{
preHead->next = b;
while(b!=NULL)
{
b=b->next;
preHead = preHead->next;
}
}
else{
preHead->next = a;
while(a!=NULL)
{
a=a->next;
preHead = preHead->next;
}
}
return preHead;
}
};
147 对链表进行插入排序(mid)
冗余链表头在处理链表增删改问题时很有用,但在处理查找时会导致代码变得复杂。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* insertionSortList(ListNode* head) {
ListNode* dummyH = new ListNode(-1);
while(head != NULL)
{
auto ptr=dummyH;
while(ptr->next!=NULL&&head->val>ptr->next->val)
{
ptr=ptr->next;
}
auto temp = ptr->next;
ptr->next = head;
head=head->next;
ptr->next->next=temp;
}
return dummyH->next;
}
};
328 奇偶链表(mid)
迭代时状态要更新的变量较多,要注意检查。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* oddEvenList(ListNode* head) {
if(head==NULL||head->next==NULL)
return head;
ListNode *oddEnd = head, *oddEndNext = head->next;
ListNode *evenEnd = head->next;
while(evenEnd->next!=NULL)
{
oddEnd->next = evenEnd->next;
evenEnd->next=evenEnd->next->next;
oddEnd->next->next=oddEndNext;
oddEnd = oddEnd->next;
if(evenEnd->next!=NULL)
evenEnd=evenEnd->next;
}
return head;
}
};