代码随想录刷题day4

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

这题完全不会,直接按照卡哥思路进行模拟:
在这里插入图片描述
从这三步的先后顺序中可以看出:需要记住两个临时地址,图中的节点1和节点3,因为第一步完成之后,如果采用临时变量记住节点1的地址,那么会丢失节点1的地址,同理,在完成第二步之后,如果不使用临时变量记住节点3的地址,也会丢失节点3的地址。

/**
 * 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 swapPairs(ListNode head) {
        ListNode curr = new ListNode(0,head);
        if(head != null && head.next != null){
            head = head.next;
        }
        while(curr.next != null && curr.next.next != null){
            ListNode temp1 = curr.next;
            ListNode temp2 = curr.next.next.next;
            // 第一步
            curr.next = curr.next.next;
            // 第二步
            curr.next.next = temp1;
            // 第三步
            temp1.next = temp2;
            // 更新curr的值,以便进行循环
            curr = curr.next.next;
        }
        return head;
    }
}

curr.next != null && curr.next.next != null这个条件很明显,如果没有同时存在两个元素,那么就不需要交换。

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

这题也是使用双指针的思想来解决:
先找到正数第N个节点, 使用right指向它,left指向第一个元素,然后不断移动,直到right.next为null这时left指向的元素就是应该被删除的元素,但是同时也要使用一个指针用来记住left的前一个元素的地址

/**
 * 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 removeNthFromEnd(ListNode head, int n) {
        ListNode cur = new ListNode(0, head);
        int count = 1;
        ListNode p = cur.next;
        ListNode back = null;
        ListNode front = cur;
        while(p != null){
            if(count == n){
                back = p;
                break;
            }else{
                count++;
                p = p.next;
            }
        }
        // 如果找不到对应索引元素,则直接返回head
        if(back == null)return head;
        p = cur.next;
        // front在左,p在中间,back在右边
        while(back.next != null){
            front = p;
            p = p.next;
            back = back.next;
        }

        front.next = p.next;

        return cur.next;

    }
}

链表相交

首先要理解链表相交的意思:不是节点里面的值相同,而是指针指向的地址相同。思路是简单的,不过很考验基本功。
因此可以先计算每个链表的长度,然后将较长的链表移动到某个位置,使得从这个位置起,链表长度和较短链表长度一样,然后挨个比较地址,一遇到相等的地址则直接返回,若直到链表末尾都没有找到相同的地址,直接返回null,证明不相交

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {

    public static int getLen(ListNode head){
        int count = 0;
        while(head != null){
            count++;
            head=head.next;
        }
        return count;
    }

    public static ListNode moveLen(ListNode head, int n){
        int count = 0;
        ListNode p = head;
        while(count < n){
            p = p.next;
            count++;
        }
        return p;
    }

    public static ListNode compare(ListNode a, ListNode b){
        while(a != b){
            a=a.next;
            b=b.next;
            if(a == null){
                return null;
            }
        }
        return a;

    }


    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        int lenA = getLen(headA);
        int lenB = getLen(headB);
        
        if(lenA > lenB){
            int l = lenA - lenB;
            ListNode pA = moveLen(headA, l);
            return compare(pA, headB);
        }else if(lenA< lenB){
            int l = lenB - lenA;
            ListNode pB = moveLen(headB, l);
            return compare(pB, headA);
        }else{
            return compare(headA,headB);
        }

    }
}

142-环形链表

这道题卡哥推了很久的原理,得出了一些结论。但是我第一感觉就是使用hashset来做,空间复杂度变高了,不过代码简单也好理解啊hh。

public class Solution {
    public ListNode detectCycle(ListNode head) {

        // 判断有没有环,本质上这里是看有没有相同的地址
        // 因此hashset又排上用场了,只是需要不断遍历。时间较长
        // 但是时间复杂度也只有O(n)
        HashSet<ListNode> set = new HashSet<>();
        ListNode p = head;
        if(p==null)return null;
        while(p != null){
            if(!set.add(p))return p;;
            p = p.next;
        }
        return null;
    }
}

总结

链表这些题就是要多看多练,感觉别无捷径,只有苦练,最后一题偷懒了,但是自己时间并不充裕,主打就是一个项目优先,论文优先。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值