面试经典150题0524

面试经典150题0524

Leetcode002 两数相加
  • 判断两个链表是否有一个为空,为空则直接返回另一个链表
  • 同时处理两个节点相同位置的节点,并使用一个next保存进位信息。
  • 处理到一个链表为空时,只循环处理另外一个链表即可,需要考虑可能存在的进位。
  • 当两个链表都处理完后,需要判断是否还存在进位,如果存在则需要新建一个节点保存。
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        if(l1 == null){
            return l2;
        }
        if(l2 == null){
            return l1;
        }
        int next = 0;
        ListNode head = new ListNode();
        ListNode curr = head;
        while (l1 != null && l2 != null){
            ListNode currNode = new ListNode();
            int val = l1.val + l2.val + next;
            currNode.val = val % 10;
            curr.next = currNode;
            curr = currNode;
            next = val / 10;
            l1 = l1.next;
            l2 = l2.next;
        }
        while (l1 != null){
            ListNode currNode = new ListNode();
            int val = l1.val + next;
            next = val / 10;
            currNode.val = val % 10;
            curr.next = currNode;
            curr = currNode;
            l1 = l1.next;
        }
        while (l2 != null){
            ListNode currNode = new ListNode();
            int val = l2.val + next;
            next = val / 10;
            currNode.val = val % 10;
            curr.next = currNode;
            curr = currNode;
            l2 = l2.next;
        }
        if(next == 1){
            curr.next = new ListNode(1);
        }
        return head.next;
    }
}
Leetcode021 合并两个有序链表

原地操作两个链表的指针,优先串联节点值小的节点。如果最后有一个链表遍历完,直接将另一个链表未遍历的节点串联到尾部即可。

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    if(l1 == null){
        return l2;
    }
    if(l2 == null){
        return l1;
    }
    ListNode res = new ListNode();
    ListNode head = res;
    while (l1 != null && l2 != null){
        if(l1.val <= l2.val){
            res.next = l1;
            l1 = l1.next;
            res = res.next;
        }
        else {
            res.next = l2;
            l2 = l2.next;
            res = res.next;
        }
    }
    if(l1 != null){
        res.next = l1;
    }
    if(l2 != null){
        res.next = l2;
    }
    return head.next;
}
Leetcode138 随机链表的复制

image-20240524153211692

遍历原来链表,创建新节点复制源节点的值,同时将原节点和新节点保存到HashMap中,在第一轮遍历中同时确定新节点的next指针。

当所有的节点创建出来后,map.get(curr).random = map.get(curr.random)通过HashMap填充新节点中的random指针。

public Node copyRandomList(Node head) {
    if(head == null){
        return head;
    }
    Node curr = head;
    Node copyHead = new Node(0);
    Node copyCurr = copyHead;
    Map<Node, Node> map = new HashMap<>();
    while (curr != null){
        Node node = new Node(curr.val);
        copyCurr.next = node;
        copyCurr = copyCurr.next;
        map.put(curr, node);
        curr = curr.next;
    }
    curr = head;
    while (curr != null){
        map.get(curr).random = map.get(curr.random);
        curr = curr.next;
    }
    return copyHead.next;
}
Leetcode092 反转链表Ⅱ

image-20240524193542035

  • 添加一个头节点,方便处理

  • 先处理left左边的节点,直接遍历即可,但是要保存left左边最后一个节点。

  • 然后处理right-left+1个待反转的元素,定义两个指针precurr分别存放当前遍历节点和前一个节点。没节点之间指针反转时,需要一个临时变量保存curr的下一个节点。

    ListNode nextNode = curr.next;
    curr.next = pre;
    pre = curr;
    curr = nextNode;
    
  • 处理完需要反转的节点,然后需要将原来left左边最后一个节点的下一个节点的next指向curr节点,也就是连接到right后面的第一个节点;另外将left左边最后一个节点的next指针指向pre节点,即第right个节点。

public static ListNode reverseBetween(ListNode head, int left, int right) {
    // 一趟扫描完成反转
    ListNode dummy = new ListNode(0, head);
    ListNode ptr = dummy;
    for(int i = 1; i < left; i++){
        ptr = ptr.next;
    }
    ListNode pre = null;
    ListNode curr = ptr.next;
    for (int i = 0; i < right - left + 1; i++) {
        ListNode nextNode = curr.next;
        curr.next = pre;
        pre = curr;
        curr = nextNode;
    }

    ptr.next.next = curr;
    ptr.next = pre;
    return dummy.next;
}
e = curr.next;
        curr.next = pre;
        pre = curr;
        curr = nextNode;
    }

    ptr.next.next = curr;
    ptr.next = pre;
    return dummy.next;
}
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值