解題思路:這個題目還是比較簡單的,用到一個非常簡單的方法就可以在0(n)時間内找到這個值。
具體的方案是一趟周遊,設立一個臨時指針pointer(初始值為第一個元素位置)和一個周遊的統
計個數(count = 0),周遊元素到達K個後,臨時指針指向第K+1個元素的位置,count清零,
重新計數,繼續周遊K個元素,直到達到連結清單尾。
這裡有兩種情況:
1.周遊完後,count剛好為K,pointer所指即使第K個元素
2. 如果count小于K,則pointer要往前移動(K-count+1)個位置。
補充:具體編碼實作後,才發現,上面的思路有一個很大的漏洞除了記錄臨時指針指向目前K個元素
的首位址外,還需要一個指針(Node* pre)記錄這個指針指向的前K個元素的首位址。
上面第2條,需要移動的指針,其實是pre, 這裡把原先錯誤的想法也記錄下來,以警醒自己,動手之
前一定要把問題想清楚,想明白。
參考代碼:
#include <stdio.h>
#include <stdlib.h>
struct Node
{
Node* next;
int value;
};
typedef Node* List;
Node* InsertNode(Node* head,int value)
{
if(head == NULL)
{
head = (Node*)malloc(sizeof(Node));
if(head == NULL)
printf("malloc failed.");
else
{
head->next = NULL;
head->value = value;
}
}
else
{
Node* cur = (Node*)malloc(sizeof(Node));
if(cur == NULL)
printf("malloc failed.");
else
{
cur->next = head;
head = cur;
cur->value = value;
}
}
return head;
}
Node* FreeLink(Node* head)
{
while(head->next)
{
Node* cur = head->next;
free(head);
head = cur;
}
return NULL;
}
void PrintLink(Node* head)
{
Node* p=head;
while(p->next)
{
printf("%d ",p->value);
p = p->next;
}
printf("%d/n",p->value);
}
int FindLastKthNode(List list, int K)
{
if(list == NULL || K < 0)
return -1;
List tmp = list;
List pre = tmp;
List p = list;
int count = 0;
int n = 0;
while(p)
{
if(p->next != NULL && count < K)
{
count++;
}
if(p->next != NULL && count == K)
{
pre = tmp;
tmp = p->next;
count = 0;
n++;
}
if(p->next == NULL && count < K)
{
if(n == 0)
printf("The length of the list is small than K.");
else
{
count++;
if(count == K)
n++;
else
{
int num = count;
while(num--)
pre = pre->next;
tmp = pre;
}
}
}
p = p->next;
}
if(n == 0)
return -1;
else
return tmp->value;
}
int main()
{
Node* link = NULL;
link = InsertNode(link, 9);
link = InsertNode(link, 8);
link = InsertNode(link, 7);
link = InsertNode(link, 6);
link = InsertNode(link, 5);
link = InsertNode(link, 4);
link = InsertNode(link, 3);
link = InsertNode(link, 2);
link = InsertNode(link, 1);
PrintLink(link);
printf("%d/n",FindLastKthNode(link,7));
FreeLink(link);
return 0;
}
2009年9月25日:其實這道題還有一個更加簡單的解法,設定兩個指針,一個
指針指向連結清單頭,另一個指向前一指針間隔為K的位置。
int FindLastKthNode2(List list, int K)
{
List p1 = list;
List p2 = list;
int i = K;
while(i > 0)
{
p2 = p2->next;
--i;
}
while(p2 != NULL)
{
p1 = p1->next;
p2 = p2->next;
}
return p1->value;
}
後記:不自己動手試一下,很難發現其中的問題,寫了個驅動程式
跑一下,發現了很多原來沒有注意到的問題,調試花了不少時間。
現在這個程式可以正确運作了,有興趣的同學可以自己寫個驅動程
序跑一下試試看。