链表OJ题练习

目录

反转链表

 找链表的中间结点

合并两个有序链表 

 相交链表找公共结点

 判断是否有环

判断一个链表是否是回文的 


反转链表

题目描述:给你单链表的头节点 head ,反转链表,并返回反转后的链表。

问题分析: 

我们可以申请三个指针,第一个指针叫 prev,最初是指向 null 的。第二个指针cur 指向 head,然后不断遍历 cur。第三个变量temp是一个临时变量,用来保存cur下一个节点。每次迭代到 cur,都将 cur 的 next 指向 prev,然后 prev 和 cur 前进一位。都迭代完了(cur 变成 null 了),pre 就是最后一个节点了。

代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode cur=head;
        ListNode prev=null;
        ListNode temp=null;
        while(cur!=null){
            temp=cur.next;
            cur.next=prev;
            prev=cur;
            cur=temp;
        }
        return prev;
    }

}

 找链表的中间结点

题目描述:

给定一个头结点为 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。

问题分析:

定义一个快指针,一个慢指针,开始都指向头结点,快指针每次走两步,慢指针每次走一步,当快指针变成null了,慢指针指向的位置就是中间结点的位置。

代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode middleNode(ListNode head) {
        ListNode fast=head;
        ListNode slow=head;
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        }
        return slow;
    }
}

合并两个有序链表 

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

问题分析: 创建一个新的链表,依次比较两个链表,把小的放入新链表,再往后走一步,如果有一个链表为空,就直接指向另一个链表。

代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode prevhead=new ListNode(-1);
        ListNode prev=prevhead;
        while(list1!=null && list2!=null){
            if(list1.val<list2.val||list1.val==list2.val){
                prev.next=list1;
                list1=list1.next;
            }else{
                prev.next=list2;
                list2=list2.next;
            }
            prev=prev.next;
        }
        
        if(list1==null){
            prev.next=list2;
        }else{
            prev.next=list1;
        }
        return prevhead.next;
    }
}

 相交链表找公共结点

问题描述:给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 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) {
        if(headA==null||headB==null){
            return null;
        }
        ListNode pl=headA;//长链表
        ListNode ps=headB;//短链表
        int lenA=0;
        int lenB=0;
        while(pl!=null){
            lenA++;
            pl=pl.next;
        }
        while(ps!=null){
            lenB++;
            ps=ps.next;
        }
        pl=headA;
        ps=headB;
        int len=lenA-lenB;
        if(len<0){
            pl=headB;
            ps=headA;
            len=lenB-lenA;
        }
        for(int i=0;i<len;++i){
            pl=pl.next;
        }
        while(pl!=ps){
            pl=pl.next;
            ps=ps.next;
        }
        if(pl==null&&ps==null){
            return null;
        }
        return ps;
    }
}

 判断是否有环

题目描述:给你一个链表的头节点 head ,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。

 题目分析:快慢指针,分别定义一个快指针,一个慢指针,让快指针每次走两步,慢指针每次走一步,如果它们相遇,就说明有环。

代码:

/**
 * 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) {
        if(head==null||head.next==null){
            return false;
        }
        ListNode fast=head;
        ListNode slow=head;
        while(fast!=null&&fast.next!=null){
            fast=fast.next.next;
            slow=slow.next;
            if(fast==slow){
                return true;
            }
        }
        return false;
    }
}

判断一个链表是否是回文的 

题目描述:给定一个head判断这个链表是否是回文的,不是返回false,是返回true;

题目分析:第一步,找到中间结点;第二步,翻转后半部分链表;第三步,判断是否回文

代码:

/*
public class ListNode {
    int val;
    ListNode next = null;

    ListNode(int val) {
        this.val = val;
    }
}*/
public class PalindromeList {
    public boolean chkPalindrome(ListNode A) {
        // write code here
        if(A==null||A.next==null){
            return true;
        }
        //找到中间结点
        ListNode slow=A;
        ListNode fast=A;
        while(fast!=null&&fast.next!=null){
            slow=slow.next;
            fast=fast.next.next;
        }
        //翻转链表
        ListNode cur=slow.next;
        slow.next=null;
        ListNode prev=null;
        ListNode next=null;
        while(cur!=null){
            next=cur.next;
            cur.next=prev;
            prev=cur;
            cur=next;
        }
        //判断是否回文
        while(A!=null&&prev!=null){
            if(A.val!=prev.val){
                return false;
            }
            A=A.next;
            prev=prev.next;
        }
        return true;
    }
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值