链表
链表是一种常见的数据结构,在许多算法题里都有以链表为基本蓝图的题目,我们一起来看看。
分析: 对于链表的每一个节点,都是一个元素加上一个next指针。想要反转链表,其实只需要每一个节点指向下一个元素的next指针,转而指向上一个元素即可。
下面是代码示例:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head) {
struct ListNode dummy;
dummy.next = NULL;
struct ListNode* tmp;
while (head) {
tmp = head->next;
head->next = dummy.next;
dummy.next = head;
head = tmp;
}
return dummy.next;
}
分析: 这道题需要我们去输出倒数第cnt个节点元素,我的第一反应就是按照上面那道例题的方式首先进行原地逆秩,然后再输出顺数的第cnt个节点元素。 那么有没有更加高效的方法呢?当然,我们可以采用快慢指针的方法,所谓快慢并不是指指针移动速度的快慢,而是两个指针相对位置的前后。我们让一个指针指向0位置,另一个指向cnt位置。两个指针同时后移,当靠后的指针指向链表尾的NULL时,靠前的指针就会指向倒数第cnt个位置。
下面是快慢指针法的代码示例:
ListNode* trainningPlan(ListNode* head, int cnt) {
ListNode* fast = head;
ListNode* slow = head;
while (fast && cnt > 0) {
fast = fast->next;
cnt--;
}
while (fast) {
fast = fast->next;
slow = slow->next;
}
return slow;
}