leetcode-----链表2

一、两链表的交点:

PS:节点类:

class ListNode {
	int val;
	ListNode next;
	ListNode(int x) { val = x; }
}

思路一: 通过set集合来判断,将链表一放入set集合中,遍历链表二,如果存在相同的值,则为交点,return结束遍历返回该交点;

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

思路二: 算出两个链表的长度,将长链表的指针移动相应的差值,使得循环时,两链表是等长的,每一次循环判断链表A的指针的B的指针的值是否是同一个,如果是,则为交点。

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        int sizeA = getSize(headA);
        int sizeB = getSize(headB);
        
        //链表A比链表B长
        if(sizeA>sizeB){
            int count = sizeA-sizeB;
            while(count>0){
                headA = headA.next;
                count--;
            }
        }else{
            int count = sizeB-sizeA;
            while(count>0){
                headB = headB.next;
                count--;
            }
        }
        while(headA!=null&headB!=null){
            if(headA == headB){
                return headA;
            }
            headA = headA.next;
            headB = headB.next;
        }
        return null;
    }

    public int getSize(ListNode listnode){
        int len = 0;
        while(listnode != null){
            len++;
            listnode = listnode.next;
        }
        return len;
    }
}

二、判断链表是否有环,返回true/fasle;

思路一:使用set集合遍历链表,如果集合中不存在则add,存在则返回true;

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

思路二:使用快慢指针,设置快指针步长为2,慢指针步长为1;遍历链表,如果两指针相遇,则true,否则是为false;Ps:while循环的条件需要判断慢指针是否为null,快指针是否为null;以及快指针的next是否为null,缺一则会出现空指针异常:

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

二、判断链表是否有环,返回入环处的节点;

思路一:同上,使用set返回的不是true/false,而是重复节点。

思路二:
1、同上,在取得相遇节点时,使用meet临时变量保存。
2、判断此时meet是否和head相同,如果相同则为入环处
3、如果不同,则使meet和head以步长为1向下遍历,知道相遇,相遇的节点则为入环处。

public class Solution {
    public ListNode detectCycle(ListNode head) {
       ListNode fast_node = head;
       ListNode slow_node = head;
       ListNode meet = null;
       while(slow_node != null && fast_node != null &&fast_node.next!=null){
           slow_node =slow_node.next;
           fast_node = fast_node.next.next;
           if(slow_node == fast_node){
               meet = slow_node;
               break;
           }
       }
       if(meet != null){
           while(head != null){
               if(head == meet){
                    return head;
                }
                head = head.next;
                meet = meet.next;
            }
       }
       return meet;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值