题目:
输入一个单向链表。如果该链表的结点数为奇数,输出中间的结点;如果链表结点数为偶数,输出中间两个结点前面的一个。
思考:
最简单的解法:从头到尾遍历一遍数组,得到链表大小n。然后再从头走n/2次,则一共需要的时间为1.5n。
优化:想起以前一道题目,用n的方法反转一个单向链表。如果只用一个变量header,是不可能的,用了preHeader,proHeader,nowHeader三个变量则变成了一种可能。那就想一想有没有空间换时间的可能性。假如一开始我用两个变量,firstHeader,secHeader,题目要求的输出结点总是结点总和的一半,那我可不可以first和sec一起走,但是每次都是sec走两下first走一下,当sec到达末尾后,first刚好走了一半。通过多了一个变量,来节约了0.5n次的时间。
代码:
struct Node{
int key;
Node* next;
};
class List{
public:
List():header(NULL){
}
Node* findNode(){
if (header==NULL)
{
return;
}
Node* first = header;
Node* sec =header;
int walkCount = 0;
while (sec!=NULL)
{
sec = sec->next;
walkCount++;
if (walkCount%2==0 && sec!=NULL)
{
first = first->next;
}
}
return first;
}
Node* header;
};