栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

LeetCode链表算法题(java版)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

LeetCode链表算法题(java版)

文章目录
  • 前言
    • 敲敲敲
  • 一、反转链表
  • 二、链表的中间节点(力876)
  • 三、倒数第k个节点(剑22)
  • 四、分割链表
  • 五、回文链表
  • 六、环形链表(力141)
  • 七、两个链表的第一个公共节点(剑52)
  • 八、第一个入环节点(拓展)
  • 九、再熟悉一下链表在ACM模式下的输入输出


前言 敲敲敲

在写链表的算法题之前先手撕一下链表的几个基本功能吧。(一定要多练习!!!)
潜意识里要形成使用this的好习惯,不然以后bug把头找秃

class Node{
    public int data;
    public Node next;
    public Node(int data){
        this.data = data;
    }
}
public class SinglelinkedList {
    public Node head;

    //头插法
        public void addFirst(int data){

            Node node =new Node(data);
            if(this.head==null){
                this.head=node;
                return;
            }
            node.next=this.head;
            this.head=node;
        }
        
        //打印
    public void display(){
            Node cur=this.head;
            while(cur!=null){
                System.out.print(cur.data);
                cur=cur.next;
            }
        System.out.println();
     }


    //尾插法
     public void addEnd(int data){
            Node node =new Node(data);
            if(this.head==null){
                this.head=node;
                return;
            }
            Node cur=this.head;
            while(cur.next!=null){
                cur=cur.next;
            }
            cur.next=node;
     }


     //判断链表中是否存在key值
     public boolean contains(int key){
            Node cur=this.head;
            while(cur!=null){
                if(cur.data==key){
                    return true;
                }
                cur=cur.next;
            }
            return  false;
     }

     //得到链表长度
    public int size(){
            Node cur=this.head;
            int count=0;
            while(cur!=null){
                count++;
                cur=cur.next;
            }
            return  count;
    }


    //在index(从1开始的)位置插入元素
    public void addIndex(int index,int data){
            Node note=new Node(data);
            if(index==0){
                addFirst(data);
                return;
            }
            if(index==this.size()){
                addEnd(data);
                return;
            }
            Node cur=this.head;
            while(index-1!=0){
                cur=cur.next;
                index--;
            }
            note.next=cur.next;
            cur.next=note;
    }


    //删除第一次出现的key值
    public void deleteKey(int key){
            if(this.head==null){
               throw new RuntimeException("链表已经空了");
            }
            if(this.head.data==key){
                this.head=this.head.next;
                return;
            }
            Node prev=searchPrev(key);
            if(searchPrev(key)==null){
                System.out.println("没有要删除的元素");
                return;
            }
            prev.next=prev.next.next;
    }

    private Node searchPrev(int key){
            Node prev=this.head;
            while(prev.next!=null) {
                if (prev.next.data == key) {
                    return prev;
                } else {
                    prev = prev.next;
                }
            }
            return null;
        }
        
        
    //删除所有出现的key值
    public void removeAll(int key){
            if(this.head==null){
                throw new RuntimeException("链表已经空了");
            }
            Node prev=this.head;
            Node cur=prev.next;
            while(cur!=null){
                if(cur.data!=key){
                    prev=prev.next;
                    cur=cur.next;
                }else{
                    prev.next=cur.next;
                    cur=cur.next;
                }

            }
            if(this.head.data==key){
                this.head=this.head.next;
            }
    }

   //清空链表
    public void clear(){
            this.head=null;
    }

}

一、反转链表

题目:

代码:

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode prev=null;
        ListNode cur=head;
        ListNode newHead=null;
        ListNode curNext=null;
        while(cur!=null){
            curNext=cur.next;
            if(curNext==null){
                newHead=cur;   新的链表的头结点就是老链表的头结点
            }
            cur.next=prev;    让后面的节点指向前面的节点完成翻转
            prev=cur;        前驱节点向后移动
            cur=curNext;  cur节点向后移动,curNext相当于一个临时变量储存cur的下一个节点,
        }
        return newHead;
    }
}
二、链表的中间节点(力876)

题目:

class Solution {
    public ListNode middleNode(ListNode head) {
        ListNode curSlow=head;                         快慢指针法,快指针走两下慢指针走一下,
                                                       只要快指针不为null(奇数个节点)或者快指针
                                                       的下一个节点不为null(偶数个节点)就继续走。
        ListNode curFast=head;
        while(curFast!=null&&curFast.next!=null){
                curSlow=curSlow.next;
                curFast=curFast.next.next;
        }
        return curSlow;
    }
}
三、倒数第k个节点(剑22)

题目:

class Solution {
    public ListNode getKthFromEnd(ListNode head, int k) {
        ListNode fast=head;
        ListNode slow=head;
        if(k<=0){                  k合法性判断
            return head;
        }                                     
        int n=k-1;                    让快指针先走k-1步,然后快慢指针一起走,当快指针.next为null                                
        while(n>0){                   则停止。此时slow所指向的位置就是要返回的头结点。
            fast=fast.next;
            n--;                     注意一下循环条件中fast!=null指的是最终fast将指向null,而
        }                            fast.next!=null指的是最终fast会指向最后一个节点,这里应该用
        while(fast.next!=null){      后者
            fast=fast.next;
            slow=slow.next;
        }
        return slow;
    }
}
四、分割链表

题目:

class Solution {
    public ListNode partition(ListNode head, int x) {
            ListNode bs=null;
            ListNode be=null;         创建了四个节点分别指向前链表的头尾结点。后链表的头尾节点。cur                     
            ListNode as=null;         用来遍历原始链表。
            ListNode ae=null;
            ListNode cur=head;
            while(cur!=null){          一个一个遍历所有的节点,小于x的插入到前面的链表,大于等于x
                if(cur.val 
五、回文链表 

题目:

class Solution {
    public boolean isPalindrome(ListNode head) {
        ListNode slow=head;
        ListNode fast=head;
       // ListNode cur=head;

       if(head==null){           当链表为空力扣默认true牛客默认false
           return true;
       }
       if(head.next==null){      当链表只有一个元素肯定是啦
           return true;
       }
        while(fast!=null&&fast.next!=null){     我们先根据第二题的方法找到链表的中间节点slow
            slow=slow.next;
            fast=fast.next.next;
        }


        ListNode cur=slow.next;                  用cur来遍历从slow开始到null的所有节点,让他们
        while(cur!=null){                        指向自己前面的节点
            ListNode curNext=cur.next;           这里就和反转链表一样了,只不过把前驱结点prev换成
            cur.next=slow;                        了solw
            slow=cur;
            cur=curNext;
        }

        while(head!=slow){                 
            if(head.val!=slow.val){            这时候slow已经指向最后了,不过他这时候已经被翻转
                return false;                  往前指向了,只要不相等就不是回文
            }
            if(head.next==slow){              判断head.next是不是slow,比如元素个数为偶数1221
                return true;
            }
            head=head.next;                     分别向中间靠拢一个元素
            slow=slow.next;                    
        }
        return true;
    }
}
六、环形链表(力141)

题目:

public class Solution {
    public boolean hasCycle(ListNode head) {
        ListNode slow=head;              定义一个快慢指针指向头结点
        ListNode fast=head;
      
        while(fast!=null&&fast.next!=null){    fast和fast.next都不可以是null,不然就空指针了
            fast=fast.next.next;      快指针一次向后移动两个节点
            slow=slow.next;           慢指针一次向后移动一个节点
            if(fast==slow){           如果快指针和慢指针再次相遇则这是一个环形链表
                return true;   
            } 
            
        }
        return false;

    }
}
七、两个链表的第一个公共节点(剑52)

题目:

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        int len1=0;        
        int len2=0;
        ListNode cur1=headA; 
        while(cur1!=null){
            len1++;
            cur1=cur1.next;
        }
        ListNode cur2=headB;
        while(cur2!=null){
            len2++;
            cur2=cur2.next;
        }
        cur1=headA;
        cur2=headB;
        int len=len1-len2;
        if(len10){
            cur1=cur1.next;
            len--;
        }
        while(cur1!=cur2){              当不相等就往后走
            cur1=cur1.next;
            cur2=cur2.next;
        }
        if(cur1==cur2&&cur1!=null){         这个时候他们肯定相等,如果不是null就返回cur1
                return cur1;
        }
          return null;
    }
}
八、第一个入环节点(拓展)

题目:

数学分析一下:

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode slow=head;
        ListNode fast=head;
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
            if(slow==fast)break;
            }
            if(fast==null||fast.next==null){     找到第一次相遇的地方
                return null;
            }
            slow=head;               让slow从新指向头
            while(fast!=slow){       以相同的速度前进知道下次相遇。
                fast=fast.next;
                slow=slow.next;
            }
            return slow;             第二次相遇的地方就是咱们的入口
        }
    }

九、再熟悉一下链表在ACM模式下的输入输出
 static class ListNode{
         public int val;
         ListNode next;
        public ListNode(int val) {
            this.val = val;
        }
        public ListNode(){};
    }

    public static void main(String[] args) {

        ListNode head=new ListNode();
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();                         //放在数组中进行单链表的遍历输入
        ListNode cur=head;
        int[]nums=new int[n];
        for (int i = 0; i < n; i++) {
            nums[i]=sc.nextInt();
        }
        for (int i = 0; i 
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/601481.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号