}
----------------------------------------例题2-----------------------------------------------------------------------------------
Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes.
You should try to do it in place. The program should run in O(1) space complexity and O(nodes) time complexity.
Solution:
struct ListNode* oddEvenList(struct ListNode* head) {
if(head == NULL)
return NULL;
//第二队队首
PList SecondHead = head->next;
PList p = head; //第一队队尾
PList q = head->next; //第二队队尾
while(p->next != NULL && q->next != NULL)
{
p->next = q->next;
p = p->next;
q->next = p->next;
q = q->next;
}
p->next = SecondHead;
return head;
}
//空链表的判断一定是需要的。
----------------------------------------------------例题3--------------------------------------------------------
Write a program to find the node at which the intersection of two singly linked lists begins.
a1->a2->c1->c2->c3
b1->b2->b3->c1->c2->c3
answer: c1
Solution 1:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
PList TempHeadA = (PList)malloc(sizeof(struct ListNode));
TempHeadA = headA;
PList TempHeadB = (PList)malloc(sizeof(struct ListNode));
TempHeadB = headB;
while(TempHeadA != NULL)
{
while(TempHeadB != NULL)
{
if(TempHeadA == TempHeadB)
return TempHeadA;
TempHeadB = TempHeadB->next;
}
TempHeadA = TempHeadA->next;
TempHeadB = headB;
}
return NULL;
}
Solution 2:
利用双指针走两个链表,设L1的私有段长度为x1,L2私有段长度为x2,共有段为y。
可以得:
x1 + y + x2 + y
x2 + y + x1 + y
可以看出在前三个部分就可以让指针置于同一起跑点,所以有:
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
if(headA == NULL || headB == NULL)
return NULL;
PList TempA = (PList)malloc(sizeof(struct ListNode));
TempA = headA;
PList TempB = (PList)malloc(sizeof(struct ListNode));
TempB = headB;
while(TempA != NULL && TempB != NULL)
{
if(TempA == TempB)
return TempA;
TempA = TempA->next;
TempB = TempB->next;
}
if(TempA == NULL)
{
TempA = headB;
while(TempA != NULL && TempB != NULL)
{
if(TempA == TempB)
return TempA;
TempA = TempA->next;
TempB = TempB->next;
}
TempB = headA;
while(TempA != NULL && TempB != NULL)
{
if(TempA == TempB)
return TempA;
TempA = TempA->next;
TempB = TempB->next;
}
}
if(TempB == NULL)
{
TempB = headA;
while(TempA != NULL && TempB != NULL)
{
if(TempA == TempB)
return TempA;
TempA = TempA->next;
TempB = TempB->next;
}
TempA = headB;
while(TempA != NULL && TempB != NULL)
{
if(TempA == TempB)
return TempA;
TempA = TempA->next;
TempB = TempB->next;
}
}
return NULL;
}
------------------------------------------------------------例题4----------------------------------------------------------
Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.
Input:
[
1->4->5,
1->3->4,
2->6
]
Output: 1->1->2->3->4->4->5->6
Solution 1:从上到下,让相邻的两个链表合并成新的有序链表接着向下合并。
struct ListNode *MergeSup(struct ListNode * A,struct ListNode * B)
{
struct ListNode * TempResult = (struct ListNode *)malloc(sizeof(struct ListNode));
struct ListNode * Last = TempResult;
int count = 0;
if(!A && B)
{
while(B)
{
if(count == 0)
{
TempResult->val = B->val;
TempResult->next = NULL;
count++;
}
else
{
struct ListNode * T = (struct ListNode *)malloc(sizeof(struct ListNode));
T->val = B->val;
T->next = NULL;
Last->next = T;
Last = T;
}
B = B->next;
}
return TempResult;
}
if(!B && A)
{
while(A)
{
if(count == 0)
{
TempResult->val = A->val;
TempResult->next = NULL;
count++;
}
else
{
struct ListNode * T = (struct ListNode *)malloc(sizeof(struct ListNode));
T->val = A->val;
T->next = NULL;
Last->next = T;
Last = T;
}
A = A->next;
}
return TempResult;
}
if(!A && !B)
return NULL;
if(A->val < B->val)
{
TempResult->val = A->val;
A = A->next;
}
else
{
TempResult->val = B->val;
B = B->next;
}
TempResult->next = NULL;
while(A && B)
{
struct ListNode * TempNode = (struct ListNode *)malloc(sizeof(struct ListNode));
if(A->val < B->val)
{
TempNode->val = A->val;
A = A->next;
}
else
{
TempNode->val = B->val;
B = B->next;
}
TempNode->next = NULL;
Last->next = TempNode;
Last = TempNode;
}
while(A)
{
struct ListNode * TempNode = (struct ListNode *)malloc(sizeof(struct ListNode));
TempNode->val = A->val;
TempNode->next = NULL;
Last->next = TempNode;
Last = TempNode;
A = A->next;
}
while(B)
{
struct ListNode * TempNode = (struct ListNode *)malloc(sizeof(struct ListNode));
TempNode->val = B->val;
TempNode->next = NULL;
Last->next = TempNode;
Last = TempNode;
B = B->next;
}
return TempResult;
}
struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) {
if(listsSize == 0)
return NULL;
struct ListNode *Temp;
struct ListNode *temp;
struct ListNode *Remember;
Temp = MergeSup(NULL,lists[0]);
for(int i = 1;i < listsSize;i++)
{
Remember = Temp;
Temp = MergeSup(Temp,lists[i]);
if(Remember)
{
temp = Remember->next;
while(temp)
{
free(Remember);
Remember = temp;
temp = Remember->next;
}
free(temp);
}
}
return Temp;
}
时间复杂度是O(m*n)
Solution 2:采用两两归并的思想来进行有序的组合,上面的由于组合的时候是线性的,也就是复杂度是N,现在采用两两归并则复杂度是logn,从本题的测试数据可以得出快大约80+倍方法二。
struct ListNode* mergeKLists(struct ListNode** lists, int listsSize) {
if(listsSize == 0)
return NULL;
if(listsSize == 1)
return lists[0];
int Groups = listsSize;
int count,i;
while(Groups != 1)
{
count = 0;
if(Groups % 2 == 0)
{
for(i = 0;i < Groups-1;i+=2)
lists[count++] = MergeSup(lists[i],lists[i+1]);
Groups = Groups/2;
}
else
{
for(i = 0;i < Groups-2;i+=2)
lists[count++] = MergeSup(lists[i],lists[i+1]);
lists[count++] = MergeSup(lists[i],NULL);
//单出一组
Groups = Groups/2+1;
}
}
return lists[0];
}
--------------------------------------------------------------------例题5--------------------------------
按照前序压缩,全部变成右子树,左子树全部为NULL;
Solution 1:
复刻数据到数组,重新创建树。
typedef struct TreeNode * TList;
void Pre_GetData(TList Root,int *Data,int *count)
{
if(Root == NULL)
return;
Data[(*count)++] = Root->val;
Pre_GetData(Root->left,Data,count);
Pre_GetData(Root->right,Data,count);
}
void GetNodeNumbers(TList Root,int *count)
{
if(Root == NULL)
return;
(*count)++;
GetNodeNumbers(Root->left,count);
GetNodeNumbers(Root->right,count);
}
void flatten(struct TreeNode* root) {
if(root == NULL)
return NULL;
int NodeNumbers = 0,count = 0;
GetNodeNumbers(root,&NodeNumbers);
int *Data = (int *)malloc(sizeof(int)*NodeNumbers);
Pre_GetData(root,Data,&count);
TList Last = (TList)malloc(sizeof(struct TreeNode));
Last = root;
Last->left = NULL;
for(int i = 1;i < NodeNumbers;i++)
{
TList PNode = (TList)malloc(sizeof(struct TreeNode));
PNode->val = Data[i];
PNode->left = NULL;
Last->right = PNode;
Last = PNode;
}
Last->right = NULL;
}
-------------------------------------------例题6---------------------------------------------------
Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.
当K大于length的时候链表不动
Example:
Given this linked list: 1->2->3->4->5
For k = 2, you should return: 2->1->4->3->5
For k = 3, you should return: 3->2->1->4->5
Solution :利用栈来实现链表的反转
struct ListNode* reverseKGroup(struct ListNode* head, int k) {
if(!head || !head->next)
return head;
int length = 0;
struct ListNode *Go = head;
while(Go)
{
length++;
Go = Go->next;
}
if(k > length)
return head;
//数组模拟栈
int count;
struct ListNode** TempArray = (struct ListNode**)malloc(sizeof(struct ListNode*)*k);
for(int j =0;j < k;j++)
TempArray[j] = (struct ListNode *)malloc(sizeof(struct ListNode));
struct ListNode* p = head;
struct ListNode* TempHead = (struct ListNode *)malloc(sizeof(struct ListNode));
TempHead->next = head;
struct ListNode * Last;
int first = 0;
bool flag = true;
while(p)
{
for(count = 0;count < k;count++)
{
TempArray[count] = p;
p = p->next;
if(!p && count < k-1)
{
count++;
flag = false;
break;
}
}
if(flag)
{
for(count = count-1;count >= 0;count--)
{
if(first == 0)
{
TempHead->next = TempArray[count];
Last = TempHead->next;
first++;
}
else
{
Last->next = TempArray[count];
Last = Last->next;
}
}
}
}
//最后处理
if(count < k && count > 0)
{
for(int i = 0;i < count;i++)
{
Last->next = TempArray[i];
Last = Last->next;
}
}
Last->next = NULL;
return TempHead->next;
}