IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 链表汇总(未完待续) -> 正文阅读

[数据结构与算法]链表汇总(未完待续)

题解

双指针(快慢指针)

141. 环形链表

力扣传送门

思路一:快慢指针
假如两个人绕曹操跑步,跑的快的人必定追得上慢的人。这就是快慢指针的思想,所以通过设置步长为2和1的两个指针,从链表都出发,不断往后移,如果存在环形链表,两指针必定会相遇。

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while(slow != null && fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
            if(slow!=null && fast == slow){
                return true;
            }
        }
        return false;
    }
}

思路二:HashSet集合,具体见下一题

142. 环形链表 II

力扣传送门

思路一:借助Set集合的唯一性,往Set添加节点,若链表有循环,说明节点会重复遇到。

public class Solution {
    public ListNode detectCycle(ListNode head) {
        Set<ListNode> set = new HashSet<>();
        while(head != null) {
            if(set.contains(head)) {
                return head;
            }
            set.add(head);
            head = head.next;
        }
        return null;
    }
}

思路二:双指针,节省空间
由于快慢指针只是判断链表中有环,并不能得出相遇点就是交叉点。所以需要了解其中的一点规律才能做出:快慢指针相遇时,慢指针走到交叉节点的路径等于从首节点走到交叉节点的路径
具体证明见力扣
简单理解如下图:-4到2等于3到2的距离,-4才是相遇点

public class Solution {    
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        ListNode tmp = null;
        while(fast != null && fast.next != null && slow != null) {            
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow) {
                tmp = head;
                while(tmp != null && slow != null && tmp != slow) {
                    tmp = tmp.next;
                    slow = slow.next;
                }
                break;
            }
        }        
        return tmp;
    }
}

剑指 Offer 22. 链表中倒数第k个节点

力扣传送门

思路一:list集合(代码略)
用list集合存放所有节点,然后通过get(size-k)即可返回结果

代码略

思路二:快慢指针
让b指针先走k步,然后a指针和b指针同时开始往后走,待b走完时,a所到的位置就是倒数第k个节点,保持因为a和b的距离一直保持是k

class Solution {
    public ListNode getKthFromEnd(ListNode head, int k) {   
        ListNode tmp = head;//b指针
        while(k-- > 0) {//先走k步
            tmp = tmp.next;
        }
        while(tmp != null) {//同时走
            tmp = tmp.next;
            head = head.next;
        }
        return head;//a指针
    }
}

思路三:二次遍历
第一次先求长度len,第二遍历到len-k的位置即可

代码略

面试题 02.07. 链表相交

力扣传送门

思路一:HashMap
对每个节点进行计数(不是节点值,是节点的引用),若存在计数为2的,说明该节点为交点。

代码略

思路二:交换遍历
难以确定交点的原因在于两路径到达交点的长度不一致,于是我们可以通过交换路径实现长度一致。例如a路径长度是4,b路径长度是5,a遍历完就跳去遍历b,b遍历完就去遍历a,那么两者的长度就能得到互补,也就是9。

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode a = headA;
        ListNode b = headB;
        while(a!=b) {
            a = (a == null) ? headB : a.next;
            b = (b == null) ? headA : b.next;
        }
        return a;//b也可
    }
}

链表骚操作

237. 删除链表中的节点

力扣传送门

思路:节点删除
a->b->c->d,删除b,就是把a指向b的引用指向c即可。但是我们并不知道a指向b的引用,只知道有个引用指向b。a指向b这种属于引用删除,还有一种删除就是替换,既然删不了b,那就用c替换b,即b.val = b.next.val。对于c后面的节点就没必要用替换了,而是只需要删除c就可以,因为我们知道b指向c的引用,所以可以删除,即b.next = b.next.next

class Solution {
    public void deleteNode(ListNode node) {    	
        if(node == null) return;
        if(node.next!=null) {
            node.val = node.next.val; //替换
            node.next = node.next.next; //删除
        }        
    }
}

1290. 二进制链表转整数

思路:二进制与十进制的转化
101 = ((((0 x 2)+1) x 2)+0) x 2)+1=5
其实就是1 x 22 + 0 x 21 + 1 x 20 ,上式就是高中的秦九韶算法

class Solution {
    public int getDecimalValue(ListNode head) {
        int res = 0;
        while(head != null) {
            res = res * 2 + head.val;
            head = head.next;
        }
        return res;
    }
}

面试题 02.01. 移除重复节点

思路:HashSet
根据Set集合唯一性,如果遇到重复,就进行链表元素移除即可

class Solution {
    public ListNode removeDuplicateNodes(ListNode head) {
        HashSet<Integer> set = new HashSet();
        ListNode front = head;
        ListNode current = head;
        
        while(current != null) {
            if(set.contains(current.val)) { //存在就移除
                front.next = current.next;
            } else {
                set.add(current.val);
                front = current;     //记录上一个节点,用于删除
            }        
            current = current.next;  //遍历一个
        }
        return head;
    }
}

改进:元素有范围,可使用数组代替Set

思路二:暴力双层for循环

class Solution {
    public ListNode removeDuplicateNodes(ListNode head) {
        ListNode first = head;        
        while(first != null) {
            ListNode front = first; 
            ListNode current = first.next;               
            while(current != null) {
                if(current.val == first.val) {
                    front.next = current.next;
                } else {
                    front = current;
                }
                current = current.next;                    
            }
            first = first.next;
        }
        return head;
    }
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-05-08 08:20:57  更:2022-05-08 08:23:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 3:38:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码