玩转算法面试(三)链表问题(Java)

链表

1、在链表中穿针引线

LeetCode 206. 反转链表

206反转链表
剑指offer24
反转一个链表,节点的值不变 只是节点的next指针发生改变
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode reverseList(ListNode head) {
        if(head == null) return null;
        ListNode pre = null;
        ListNode cur = head;
        while (cur != null ) {
            // 从后往前开始改变
            ListNode next = cur.next;
            cur.next = pre;
            pre = cur;
            cur = next;
        }

        return pre;
    }
}

拓展:

  1. Reverse Linked List II

  2. Remove Duplicates from Sorted List

  3. Partition List

  4. Odd Even Linked List

LeetCode 2. 两数相加

2.两数相加
image.png

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode pre = new ListNode(0);
        ListNode cur = pre;
        int carry = 0;
        while(l1 != null || l2 != null) {
            int x = l1 == null ? 0 : l1.val;
            int y = l2 == null ? 0 : l2.val;
            int sum = x + y + carry;
            
            carry = sum / 10;
            sum = sum % 10;
            cur.next = new ListNode(sum);

            cur = cur.next;
            if(l1 != null)
                l1 = l1.next;
            if(l2 != null)
                l2 = l2.next;
        }
        if(carry == 1) {
            cur.next = new ListNode(carry);
        }
        return pre.next;
    }
}
  1. Add Two Numbers II

2、设立链表的虚拟头结点

LeetCode 203. 移除列表元素

203.移除列表元素
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        // if(head == null) return null;
        while(head != null && head.val == val) {
            head = head.next;
        }
        if(head == null) return null;
        ListNode cur = head;
        while(cur.next != null) {
            if(cur.next.val == val){
                ListNode delNode = cur.next;
                cur.next = delNode.next;
            }else cur = cur.next;
        }

        return head;
    }
}

// 虚拟节点
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        ListNode dummyNode  = new ListNode(0);
        dummyNode.next = head;
        ListNode cur = dummyNode;
        while(cur.next != null ) {
            if(cur.next.val == val) {
                cur.next = cur.next.next;
            }
            else cur = cur.next;
        }

        return dummyNode.next;
    }
}

拓展:

  1. Remove Duplicates from Sorted List II

  2. Merge Two Sorted Lists

LeetCode 24. 交换节点成对

24. 交换节点成对
image.png

image.png

image.png

image.png

/**
 * 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) {
        if(head == null) return head;
        if(head.next == null) return head;
        ListNode dummyNode = new ListNode(0);
        dummyNode.next = head;
        ListNode p = dummyNode;// 操作指针
        while(p.next != null && p.next.next != null) {
            ListNode node1 = p.next;
            ListNode node2 = node1.next;
            ListNode next = node2.next;
            node2.next = node1;
            node1.next = next;
            p.next = node2;

            p = node1;
        }

        return dummyNode.next;

    }
}

扩展:

  1. Reverse Nodes in k-Group

  2. Insertion Sort List

  3. Sort List

3、不仅仅是穿针引线

LeetCode 237. 删除列表中的节点

237. 删除列表中的节点
剑指offer18
image.png

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

4、双指针技术

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

19. 删除列表中的倒数第N个节点
剑指offer22类似
在这里插入图片描述

解法1:先遍历- -遍计算链表长度;再遍历- -遍删除倒数第n个节点

解法2:双指针+虚拟节点

image.png

/**
 * 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 dummyHead = new ListNode(0);
        dummyHead.next = head;
        ListNode p = dummyHead;
        ListNode q = dummyHead;
        for (int i  = 0; i < n + 1;i++) {
            q = q.next;
        }

        while(q != null) {
            p = p.next;
            q = q.next;
        }

        ListNode delNode = p.next;
        p.next = delNode.next;

        return dummyHead.next;
    }
}

剑指offer 52 两个链表的第一个公共节点

剑指offer52
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        int lenA = calLen(headA);
        int lenB = calLen(headB);
        int sub = Math.abs(lenA - lenB);
        ListNode curA = headA;
        ListNode curB = headB;
        if(lenA > lenB) return compareNode(headA,headB,sub);
        else return compareNode(headB,headA,sub);
    }
    // head1更长
    private ListNode compareNode(ListNode head1,ListNode head2,int sub) {
        ListNode curA = head1;
        ListNode curB = head2;
        while(sub > 0) {
                sub --;
                curA = curA.next;
            }

            while(curA != null) {
                if(curA == curB) return curA;
                else{
                    curA = curA.next;
                    curB = curB.next;
                }
            }

            return null;
    }

    private int calLen(ListNode head ) {
        if(head == null) return 0;
        int res = 0;
        while(head != null ) {
            res++;
            head = head.next;
        }

        return res;
    }
}

5、复制复杂链表(HashMap)

剑指offer 35 复杂链表的复制

剑指offer35
在这里插入图片描述

/*
// Definition for a Node.
class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}
*/
class Solution {
    public Node copyRandomList(Node head) {
        if(head == null) return head;
        Map<Node, Node> map = new HashMap<>();
        Node cur = head;
        while(cur != null) {
            map.put(cur, new Node(cur.val));
            cur = cur.next;
        }

        cur = head;
        while(cur != null) {
            map.get(cur).next = map.get(cur.next);
            map.get(cur).random = map.get(cur.random);
            cur = cur.next;
        }

        return map.get(head);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值