基础算法--链表相关算法

0 阅读1分钟

链表


链表是一种常见的数据结构,在许多算法题里都有以链表为基本蓝图的题目,我们一起来看看。

链表-1.png

分析: 对于链表的每一个节点,都是一个元素加上一个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;
}

链表-2.png

分析: 这道题需要我们去输出倒数第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;
    }