Java算法 反转链表和环形链表

小王的Java刷题日记Day3

记录刷题过程,作为笔记和分享,坚持每天刷题,每天进步,编程语言为Java。

题目一:反转链表     

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

例如:1->2->3->4->5  变为 5->4->3->2->1

思路一:头插法         时间复杂度O(n)    空间复杂度O(1)

1、我们需要将1先插入一个空节点的前边,即1->null。

2、其余节点依次头插法,将2插入到1前边,依次类推。

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode pre=null;
//从该head节点开始,移动到下一个节点,直到到达链表末尾。
       for(ListNode x=head;x!=null; x=x.next){
//对于原始链表中的每个节点,都会创建一个与原始节点(x.val)具有相同值的新节点。pre然后这个新节点被添加到链表的前面。这有效地颠倒了节点的顺序。
            pre=new ListNode(x.val,pre);
    }
    return pre;
    }
}

思路二:递归法                      时间复杂度O(n)    空间复杂度O(n)--栈的层数

1、我们想让链表反转,那么第一轮出栈,head为5,head.next则为空,返回5 。           

2、第二轮出栈,head为4,head.next为5,执行head.next.next=head也就是5.next=4,                 把当前节点的子节点的子节点指向当前节点。此时链表为1->2->3->4<->5,由于4与5互相指向,所以此处要断开所以让4.next=null,那么此时链表为1->2->3->4<-5。

3、依次类推即可。

class Solution {
    public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode newHead = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return newHead;
    }
}

题目二:环形链表

给你一个链表的头节点 head ,判断链表中是否有环。

思路一:双指针法     时间复杂度O(n)    空间复杂度O(1)

1、通过快慢指针,让慢指针指向头节点,快指针指向头节点的下一个节点。

2、若链表中存在环的话,那么快指针是提前进入环的,在某一时刻,快指针在环中一定可以追到慢指针。那么,我们依次为依据进行判断。

public class Solution {
    public boolean hasCycle(ListNode head) {
        if(head==null||head.next==null){
            return false;
        }
        ListNode slow=head;
        ListNode fast=head.next;
        while(slow!=fast){       //快慢指针不相等时,则进行循环
            if(fast==null||fast.next==null){   //若快指针指向空时,说明没有环
                return false;
            }
            slow=slow.next;
            fast=fast.next.next;
        }
        return true;
    }
}

思路二:哈希表         时间复杂度O(n)    空间复杂度O(n)

我们可以使用哈希表来存储所有已经访问过的节点。每次我们到达一个节点,如果该节点已经存在于哈希表中,则说明该链表是环形链表,否则就将该节点加入哈希表中。重复这一过程,直到我们遍历完整个链表即可。

public class Solution {
    public boolean hasCycle(ListNode head) {
        Set<ListNode> seen = new HashSet<ListNode>();  // 用于存储已经遍历过的节点
        while (head != null) {
            if (!seen.add(head)) {  //如果当前节点已经存在于集合中,说明存在环
                return true;
            }
            head = head.next;       //移动到下一节点,继续遍历
        }
        return false;               //未发现有环
    }
}

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值