Leetcode-day04-链表

两两交换链表中的节点

切入点:要交换那就得找到前一个节点,所以引入dummy node节点。然后就是画图示意一下,如果说偶数个节点,找完之后cur的next是null,如果是奇数个节点,则最后一个节点不需要交换了,就是cur.next.next==null。

然后就是具体的交换逻辑了,注意其中修改指向之后可能造成后续节点找不到,所以得用temp节点提前保存。

    public ListNode swapPairs(ListNode head) {
        ListNode dummy = new ListNode(-1,head);
        ListNode cur = dummy;
        ListNode temp,temp1;
        while(cur.next!=null && cur.next.next!=null){
            temp=cur.next;
            temp1=cur.next.next.next;
            cur.next=cur.next.next;
            cur.next.next=temp;
            temp.next=temp1;
            cur=temp;
        }
        return dummy.next;
    }

删除链表的倒数第 N 个结点

解法一双指针思想:

首先要弄一个duumy node节点,因为可能删除的是头节点,刚开始两个指针都指向dummy,快指针先走n步,然后快慢指针同时往后走,知道快指针是null,此时慢指针指向了要删除的节点,但是我们要删除结点的话得找到该节点的前一个节点,所以刚开始让快指针指向dummy的next,然后作上述操作,最终慢指针就停在了要删除的节点的上一个节点。

    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(-1,head);
        ListNode slow=dummy;
        ListNode fast=head;
        for(int i=0;i<n;i++){
            fast=fast.next;
        }
        while(fast!=null){
            slow=slow.next;
            fast=fast.next;
        }
        slow.next=slow.next.next;
        return dummy.next;

    }

解法二:借助ArrayList

放在arraylist里,删除了倒数第n个节点,然后再建立链表的next指向关系。

    public ListNode removeNthFromEnd(ListNode head, int n) {
        // 可以用ArrayList来做,先把所有节点放入arrayList,然后删除指定元素,再把arrayList的节点建立链表指向关系,返回头节点
        ArrayList<ListNode> arrayList = new ArrayList<>();
        ListNode node = head;
        while (node != null) {
            arrayList.add(node);
            node = node.next;
        }
        // 如果给定链表为空,返回head
        if (arrayList.size() == 0) {
            return head;
        }
        // 移除指定元素
        arrayList.remove(arrayList.size() - n);
        //如果移除后为空,返回null
        if (arrayList.size() == 0) {
            return null;
        }
        
        head = arrayList.get(0);
        node = head;
        for (int i = 0; i < arrayList.size() - 1; i++) {
            node.next = arrayList.get(i + 1);
            node = node.next;
        }
        node.next = null;
        return head;

    }

面试题 02.07. 链表相交

解法一:双指针 TODO

解法二:借助HashSet

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

环形链表 II

解法一:快慢指针 TODO

解法二:借助HashSet

用HashSet,遍历链表中的每个节点,记录到HashSet中;一旦遇到了此前遍历过的节点,就存在环,返回该结点。

    public ListNode detectCycle(ListNode head) {
        HashSet<ListNode> hashset = new HashSet<>();
        ListNode node = head;
        while(node!=null){
            if(hashset.contains(node)){
                return node;
            }
            hashset.add(node);
            node = node.next;
        }
        return null;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值