算法训练第四天 |24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、142.环形链表II

24. 两两交换链表中的节点

力扣题目链接

我的代码实现:

public ListNode swapPairs(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode newhead = head.next;
        ListNode pre = head ,fir ,sec ;
        head.next = newhead.next;
        newhead.next = head;
        if(pre != null){
            fir = pre.next;
            if(fir != null){
                sec = fir.next;

                while (fir != null && fir.next !=null){
                    pre.next = sec;
                    fir.next = sec.next;
                    sec.next = fir;
                    pre = fir;

                    if(pre != null){
                        fir = pre.next;
                    }if(fir != null){
                        sec = fir.next;
                    }

                }
            }

        }
        return newhead;
    }

在我实现的过程中首先对头结点和第二个节点是否为空进行判断,如果头节点为空或第二个节点为空(只有一个节点,不需进行交换),则直接返回head,否则的话因为头结点的原因,需要单独先对前两个元素进行处理,

从后往前进行链接,先将newhead赋值为链表的第二个节点,作为以后的返回值,然后把原链表的第二个节点的next赋给原链表头节点的next,然后将原链表的第二个节点的next赋为原链表头节点的head,然后将原链表头节点赋给pre,

接下来判断pre是否为空(这里应该没什么用),如果为空则把pre.next赋值给fir,接下来判断fir.next是否为空,如果为空不进入if分支直接return newhead(只剩fir一个数据没做处理,但因为只有一个数据,不需要做交换,所以直接返回),如果不为空则进入循环,

对pre,fir,sec,三个指针进行处理,从后往前进行连接,交换fir和sec,pre作为辅助节点存储fir的父节点,直至fir为空或fir.next为空(只剩0个或1个未处理节点)。然后返回newhead。

在老师给的解法中,老师利用了一个虚拟头节点dummyhead,省去了我对头结点和第二个节点的单独处理,也就是创建虚拟节点dummyhead,next指向head,而将这个节点作为pre,对第一个节点和第二个节点进行操作。在循环结束后直接而返回虚拟节点的next。

19.删除链表的倒数第N个节点

力扣题目链接

我的代码实现:

    public ListNode removeNthFromEnd(ListNode head, int n) {
        List<ListNode> list = new ArrayList<ListNode>();
        ListNode node = head;
        while (node!=null){
            if(list.size()>n){
                list.remove(0);
            }
            list.add(node);
            node = node.next;
        }
        if(list.size() == n+1){
            list.get(0).next = list.get(0).next.next;
        }
        if(list.size() == n){
            head = list.get(0).next;
        }
        return head;

    }

在我的实现方法中我利用了ArrayList,从头开始遍历链表,依次将每个节点加入list中,当list的大小大于n的时候,先移除第一个元素后再继续在尾部添加元素,遍历完成后,通过判断list的大小进行处理,

如果 list.size() == n+1 说明待删除节点不是头结点,list.get(0)是待删除节点的父节点,下一个节点就是待删除节点,然后进行删除。

如果 list.size() == n 说明待删除节点是头结点,需要对头节点进行重新赋值,

如果以上两种条件都不满足,因为循环里的remove操作 list.size不可能大于 n+1 所以只剩下 list.size < n的情况没做处理,当这种情况时说明输入值不合法,不需做处理。

最后返回处理后的头结点。

在老师给的解法中运用了双指针,快指针比慢指针快n+1个节点,当快指针指空时慢指针指的就是待删除节点的父节点,这也比我简单太多了吧o(╥﹏╥)o

面试题 02.07. 链表相交

力扣题目链接

我的代码实现:

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ArrayList<ListNode> list1 = new ArrayList<ListNode>();
        ArrayList<ListNode> list2 = new ArrayList<ListNode>();
        ListNode l = null;
        while (headA != null){
            list1.add(headA);
            headA = headA.next;
        }
        while (headB != null){
            list2.add(headB);
            headB = headB.next;
        }
        if(headA == headB){
            return headA;
        }
        while (!list1.isEmpty() && !list2.isEmpty()){
            if(list1.get((list1.size()-1)) == list2.get((list2.size()-1))){
                l = list1.remove((list1.size()-1));
                list2.remove((list2.size()-1));
            }else {
                return l;
            }

        }
        if (list1.isEmpty())
            return headA;
        else
            return headB;

    }

在这道题里我又用了两个list,将每个链表存入list中,然后从后面开始对比,发现不一样的节点的下一个节点就是汇聚的节点。如果从一开始就不一样就是没有汇聚的链表。

老师给的解法是获得两个链表的长度,获得两个链表的差值,然后长的链表从差值开始,这样两个链表就同步了,回顾我的代码。。好愚蠢o(╥﹏╥)o

142.环形链表II

力扣题目链接

我的代码

public ListNode detectCycle(ListNode head) {

        ArrayList<ListNode> arrayList = new ArrayList<>();
        while (head!=null){
            if(arrayList.contains(head)){
                return head;
            }else {
                arrayList.add(head);
                head = head.next;
            }
        }
        return head;
    }

在这道题里我又双叒用了一个list,从头开始遍历,把每个节点头加入到list里,加入前先判断list是否存在当前对象,如果存在了就说明当前节点是环形入口直接返回,否则接着往下遍历,直至head 为null,说明list里没有重复的节点,说明没有环,返回null。

老师给的解法是双指针,快指针一次走两步,慢指针一次走一步,在圈里慢指针会遇到快指针。没有遇到遍历到头就说明没环

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值