力扣hot100——反转,环形链表 + 快慢指针总结

1.反转链表

解法思路:

将链表划分为俩部分; 将后半部分反转,然后与前部分对比,如果相同则为回文,否则不是

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {

        // 快慢指针划分容器,一分为二
        // 定义快慢指针,相差位置1 ; 当快指针不为空且下一个位置不为空;则慢指针移动 1,快指针移动 2
        // 慢指针所指位置就是划分点; 
        // 奇数长度时,慢指针指向的就是居中那个位置; 偶数时指向为第一位部分的右端点

        // 根据上面方法将链表划分为俩部分; 将后半部分反转,然后与前部分对比,如果相同则为回文,否则不是
        
        // 快慢指针
        ListNode *slow = head, *fast = head->next;
        
        while(fast  && fast->next ){
            slow = slow->next;
            fast = fast->next->next;
        }
        // 从slow的下一个位置开始反转
        ListNode *second = reverseList(slow->next);
        // 将链表分割开
        slow->next = NULL;
        // 对比俩部分
        ListNode *first = head;
        while(second){ // 当第二部分指针不为空
            if(first->val != second->val){
                return false;
            }
            first = first->next;
            second = second->next;
        }
        return true;
        
    }
    ListNode* reverseList(ListNode* head) {
        ListNode* prev = nullptr;
        ListNode* curr = head;
        while (curr != nullptr) {
            ListNode* nextTemp = curr->next; // 临时保存下一个节点
            curr->next = prev;               // 反转当前节点的指针
            prev = curr;                     // 移动prev到当前节点
            curr = nextTemp;                 // 移动curr到下一个节点
        }
        return prev; // prev现在是反转后链表的头节点
    }
};

2.环形链表

解法思路:

// 快慢指针法,存在环,则因为指针速度不同,在寻找中,快指针一定会追上慢指针;

// 快慢指针出发点可以相同也可以不同

cpp 复制代码
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        // 快慢指针法,存在环,则因为指针速度不同,在寻找中,快指针一定会追上慢指针;
        // 快慢指针出发点可以相同也可以不同
        if(head == nullptr ||head->next == nullptr ){
            return false;
        }
        ListNode *slow = head, *fast = head->next;
        while (slow != fast) {
            if (fast == nullptr || fast->next == nullptr) {
                return false;
            }
            slow = slow->next;
            fast = fast->next->next;
        }
        return true; 
    }
};

快慢指针总结:

快慢指针算法广泛用于线性表操作,通常让快慢指针(同一位置/相差1位置)开始移动。

慢指针每次移动一步。

快指针每次移动两步。

举例:

链表划分为两个相等的部分,:

  1. 让快指针和慢指针都从链表的头部开始。
  2. 慢指针每次移动一步。
  3. 快指针每次移动两步。
  4. 当快指针到达链表末尾时(或者快指针的下一个节点为空时,意味着链表长度为奇数,快指针已经走过了中点),慢指针将位于链表的中点附近。
  5. 此时,以慢指针所在的位置为分界点,将链表划分为两部分。

检测链表中是否存在环

  • 慢指针每次移动一步。
  • 快指针每次移动两步。

当链表中存在环时,由于快指针相对于慢指针的速度优势,它们最终会在环内的某个位置相遇。

相关推荐
꧁Q༒ོγ꧂3 分钟前
算法详解---大纲
算法
m0_603888719 分钟前
Scaling Trends for Multi-Hop Contextual Reasoning in Mid-Scale Language Models
人工智能·算法·ai·语言模型·论文速览
Xの哲學12 分钟前
Linux io_uring 深度剖析: 重新定义高性能I/O的架构革命
linux·服务器·网络·算法·边缘计算
comli_cn19 分钟前
残差链接(Residual Connection)
人工智能·算法
Aaron158826 分钟前
基于VU13P在人工智能高速接口传输上的应用浅析
人工智能·算法·fpga开发·硬件架构·信息与通信·信号处理·基带工程
予枫的编程笔记28 分钟前
【论文解读】DLF:以语言为核心的多模态情感分析新范式 (AAAI 2025)
人工智能·python·算法·机器学习
im_AMBER37 分钟前
Leetcode 99 删除排序链表中的重复元素 | 合并两个链表
数据结构·笔记·学习·算法·leetcode·链表
王老师青少年编程1 小时前
信奥赛C++提高组csp-s之欧拉回路
c++·算法·csp·欧拉回路·信奥赛·csp-s·提高组
墨有6661 小时前
数学分析栈的出栈顺序:从算法判断到数学本质(卡特兰数初探)
c++·算法·数学建模
zhutoutoutousan1 小时前
氛围数学学习:用游戏化思维征服抽象数学
学习·算法·游戏