链表随笔

链表数据结构:

public class LinkedList{
     int val;
     LinkedList next;
     public LinkedList(int val){this.val = val;}
}

1\翻转链表  Leetcode 206

关键为对下一个next的备份,对上一个节点的记录(temp)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        if(head==null) return head;
        if(head.next == null) return head;
        ListNode next; //备份
        ListNode temp = null;
        while(head!=null)
        {
            next=head.next;
            head.next = temp;
            temp=head;
            head=next;
        }
        return temp;
    }
}

2\翻转链表2 Leetcode 92

反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseBetween(ListNode head, int m, int n) {
        if(head.next==null) return head;

        ListNode temphead = head;
        ListNode before = null;
        for(int i=0;i<m-1;i++)
        {
            before = temphead;
            temphead = temphead.next;
        }
        ListNode begin = temphead;
        ListNode temp = null;
        ListNode tempbf = null;
        for(int i=0;i<n-m+1;i++)
        {
            temp = temphead.next;
            temphead.next=tempbf;
            tempbf=temphead;
            temphead=temp;
        }
        begin.next=temphead;
        if(before==null) return tempbf;  //注意是不是从第一个开始翻转
        else before.next = tempbf;
        return head;

    }
}

3\求两个链表的交点 Leetcode 160 https://leetcode-cn.com/problems/intersection-of-two-linked-lists/

方法一 暴力法:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode a = headA;
        ListNode b = headB;
        while(a!=null)
        {
            b = headB;
            while(b!=null)
            {
                if(a==b)
                {
                    return b;
                }
                b = b.next;
            }
            a = a.next;
        }
        return null;
    }
}

方法二 快慢指针:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {

        ListNode a = headA;
        ListNode b = headB;
        int lena =0;
        int lenb =0;
        while(a!=null)
        {
            lena++;
            a=a.next;
        }
        while(b!=null)
        {
            lenb++;
            b=b.next;
        }
        a=headA;
        b=headB;
        if(lena>lenb)
        {
            for(int i=0;i<lena-lenb;i++)
            {
                a=a.next;
            }
        }
        else
        {
            for(int i=0;i<lenb-lena;i++)
            {
                b=b.next;
            }

        }
        if(a==b) return a;
        do{
            a = a.next;
            b = b.next;
        }while(a!=b);
        if(a==null) return null;
        else return a;
    }
}

4\链表求环 Leetcode141

给定一个链表,判断链表中是否有环。快慢指针。

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        if(head==null||head.next==null) return false;

        while(fast!=null&&slow!=null)
        {
            fast = fast.next;
            if(fast!=null) fast = fast.next;
            else return false;
            slow = slow.next;
            if(slow==fast) return true;
        }
        return false;
    }
}

5\链表求环2 leetcode142

推导 快指针(2)走过的路程是慢指针(1)的两倍 则在h点相遇时 (F+a)*2+n*(a+b)= F+a+b+a+n*(a+b) 则F=b

所以从head与h出发,能找到环的起始节点

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        ListNode meet = null;
        if(head==null||head.next==null) return null;

        while(fast!=null&&slow!=null)
        {
            fast=fast.next;
            if(fast!=null) fast = fast.next;
            else return null;
            slow = slow.next;
            if(fast==slow)
            {
                meet=fast;
                break;
            }
        }
        if(meet!=null)
        {
            while(head!=meet)
            {
                head=head.next;
                meet=meet.next;
            }
            return meet;
        }
        return null;
    }
}

6\分隔链表 leetcode 64

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。

你应当保留两个分区中每个节点的初始相对位置。

使用临时节点保存

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode partition(ListNode head, int x) {
        ListNode small = null;
        ListNode smptr = null;

        ListNode large = null;
        ListNode lgptr = null;
        if(head==null) return null;
        while(head!=null)
        {

            if(head.val<x)
            {

                if(small==null)
                {
                    small = head;
                    smptr = head;
                }
                else
                {
                    smptr.next = head;
                    smptr = head;
                }
            }
            else
            {

                if(large==null)
                {
                    large = head;
                    lgptr = head;
                }
                else{
                    lgptr.next = head;
                    lgptr = head;
                }
            }
            head = head.next;
        }

        if(small==null) return large;
        smptr.next = large;
        if(large!=null) lgptr.next = null;
        return small;

    }
}

7\链表深拷贝 太难 leetcode 138

8\链表合并 leetcode 21

将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        //应用临时节点
        ListNode newhead = null;
        ListNode ptr = null;
        if(l1==null) return l2;
        if(l2==null) return l1;
        while(l1!=null&&l2!=null)
        {
            if(l1.val<l2.val)
            {
                if(newhead==null)
                {
                    newhead = l1;
                    ptr = newhead;
                }
                else
                {
                    ptr.next = l1;
                    ptr = l1;
                }
                l1 = l1.next;
            }
            else{
                if(newhead==null)
                {
                    newhead = l2;
                    ptr = newhead;
                }
                else
                {
                    ptr.next = l2;
                    ptr = l2;
                }
                l2 = l2.next;
            }
        }
        if(l1==null)
        {
            ptr.next = l2;

        }
        else ptr.next = l1;
        return newhead;
    }
}

9\合并链表2 Leetcode23 https://leetcode-cn.com/problems/merge-k-sorted-lists/

合并 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 太难。

原文地址:https://www.cnblogs.com/luiyuying/p/12676299.html

时间: 2024-10-26 22:00:40

链表随笔的相关文章

日常学习随笔-数组、单链表、双链表三种形式实现栈结构的基本操作

一.栈结构 栈(stack)是限制插入和删除只能在一个位置上的表,该位置是 表的末端,叫做栈的顶(Top).对栈的基本操作有push(进栈),pop(出栈),peak(栈顶元素),size(栈容量)等. 栈的核心思想:"先进后出". 二.案例一:数组实现"栈" 1 package com.xfwl.algorithmAnalysis.stack; 2 3 import java.util.Arrays; 4 5 /** 6 * 自定义栈结构(基于数组的形式) 7 *

日常学习随笔-用链表的形式实现普通二叉树的新增、查找、遍历(前、中、后序)等基础功能(侧重源码+说明)

一.二叉树 1.二叉树的概念 二叉树是每个节点最多有两个子树的树结构.通常子树被称作"左子树"(left subtree)和"右子树"(right subtree),其次序不能任意颠倒. 2.性质 (1)若二叉树的层次从0开始,则在二叉树的第i层至多有2^i个结点(i>=0): (2)高度为k的二叉树最多有2^(k+1) - 1个结点(k>=-1). (空树的高度为-1): (3)对任何一棵二叉树,如果其叶子结点(度为0)数为m, 度为2的结点数为n,

数据结构与算法-单向链表

概述 由于最近在工作中需要用到树形结构来解决一些问题,所以萌生了系统学习“数据结构和算法”的想法,于是乎从最简单的表结构开始.由于数组是最简单的表结构的实现,也是各个编程语言内置的数据类型,所以不做更多的记录.表结构中以下实现打算学习: LinkedList Stack Queue HashTable Dictionary 本篇为学习数据结构的第一篇随笔,从最简单的单向链表开始吧. 实现(C#) 平台:dotNet Core 1.0, C# IDE:VSCode 如果考虑算法复用的话,可以实现泛

Mysql事务随笔

一.什么是事务 数据库中的概念,按我个人理解:能够保证一组任务全部执行成功或者全部执行失败的这么个机制,叫事务 事务是数据库中重要概念,如果没有这种保障机制,数据库中的数据就是不安全的(就是无法保证数据的正确性) 在数据库中,一组任务,就是放在一起执行的多条sql 二.ACID保证数据安全 所以如何才能保证数据安全呢?前人总结了如下四点 1.原子性,一组任务全部执行成功或者全部执行失败.这是基础,因为我们一组操作一般是有顺序的,有互相依赖关系的,要同步的,不能A表修改了,B表修改失败,这样数据就

双链表代码实现和讲解

1.什么是链表 请移步看我前一篇https://www.cnblogs.com/han200113/p/11549338.html 2.双链表和单链表有什么不同?                                双链表相比单链表的date域(节点内容)和next(指向下一个节点)多了一个pre(指向前一个节点) 单链表只能向后或向后查找,而双链表由于有节点pre,可实现向前和向后查找 单链表的删除需要借助前一个节点,双链表可改变自身前后节点的指向实现自我删除(详情看代码部分) 3.

Redis内存模型及应用解读 读后随笔

文章出处: Redis内存模型及应用解读 https://dbaplus.cn/news-158-2127-1.html 第一部分:Redis内存统计 随笔:这一部分略显枯燥,是通过redis-cli连接redis后对于info命令的结果字段解读,属于较底层的部分,熟悉redis在操作系统中的实现会更容易理解这部分. 这段对于我的帮助 1.redis进程运行本身会需要内存和内存碎片,同时redis中还存在虚拟内存 2.mem_fragmentation_ratio表示内存碎片比率,mem_fra

Linux内核链表复用实现队列

有了前面Linux内核复用实现栈的基础,使用相同的思想实现队列,也是非常简单的.普通单链表复用实现队列,总会在出队或入队的时候有一个O(n)复杂度的操作,大多数采用增加两个变量,一个head,一个tail来将O(n)降成O(1).但是在内核链表中,天然的双向循环链表,复用实现队列,无论出队还是入队,都是O(1)时间复杂度. /* main.c */ #include <stdio.h> #include <stdlib.h> #include "queue.h"

c语言动态链表的创建

创建动态连链表就是将一个个节点连接起来 (1)动态生成节点 (2)输入节点数据 (3)将节点链在一起 例: typedef struct Data { char num[20]; char name[10]; char sex; float english; float chinese; float math; }; typedef struct Node { struct Data data;//结构体类型//结构体嵌套 struct Node* next;//结构体指针型 }node,*Pn

算法学习——单链表快排

/**  * 以p为轴对start-end间的节点进行快排(包括start && 不包括end):  * 思路:  * 1.将头节点作为轴节点start,从start.next开始遍历,如果节点小于轴start的值,将该节点插入到轴节点后面:  * 2.将轴节点插入合适位置,即找到最后一个小于轴的节点,将该节点与轴节点值互换,此时就链表分为两部分,小于轴节点和大于轴节点:  * 3.递归的遍历2中两部分节点.  *   * @param p  * @param start  * @para