开发人员必须掌握的高频算法题之链表(2)

1.移除链表元素
删除链表中等于给定值 val 的所有节点。

  public class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
        }
    }


public ListNode removeElements(ListNode head, int val) {
        ListNode dy = new ListNode(-1);
        dy.next = head;
        ListNode curNode = dy;

        while (curNode.next != null) {
            if (curNode.next.val == val) {
                curNode.next = curNode.next.next;
            } else {
                curNode = curNode.next;
            }
        }

        return dy.next;
    }

2.设计链表
在链表类中实现这些功能:
1. get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
2. addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
3. addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
4. addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
5. deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。

 class MyLinkedList {

        ListNode head = null;

        /**
         * Initialize your data structure here.
         */
        public MyLinkedList() {

        }

        /**
         * Get the value of the index-th node in the linked list. If the index is invalid, return -1.
         */
        public int get(int index) {
            if (head == null) {
                return -1;
            } else {
                ListNode node = head;
                for (int i = 0; i < index; i++) {
                    node = node.next;
                    if (node == null) {
                        return -1;
                    }
                }
                return node.val;
            }
        }

        public ListNode getNode(int index) {
            if (head == null) {
                return head;
            } else {
                ListNode node = head;
                for (int i = 0; i < index; i++) {
                    node = node.next;
                    if (node == null) {
                        return node;
                    }
                }
                return node;
            }
        }

        /**
         * Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list.
         */
        public void addAtHead(int val) {
            if (head == null) {
                head = new ListNode(val);
            } else {
                ListNode node = new ListNode(val);
                node.next = head;
                head = node;
            }
        }

        /**
         * Append a node of value val to the last element of the linked list.
         */
        public void addAtTail(int val) {
            if (head == null) {
                head = new ListNode(val);
            } else {
                ListNode node = head;
                while (node.next != null) {
                    node = node.next;
                }
                node.next = new ListNode(val);
            }
        }

        /**
         * Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted.
         */
        public void addAtIndex(int index, int val) {
            if (index <= 0) {
                addAtHead(val);
            } else {
                ListNode preNode = getNode(index - 1);
                ListNode nextNode = getNode(index);
                ListNode culNode = new ListNode(val);

                preNode.next = culNode;
                culNode.next = nextNode;
            }
        }

        /**
         * Delete the index-th node in the linked list, if the index is valid.
         */
        public void deleteAtIndex(int index) {
            if (index == 0) {
                head = head.next;
            } else {
                ListNode node = getNode(index - 1);
                if (node != null && node.next != null) {
                    node.next = node.next.next;
                }
            }
        }
    }

3.反转链表
题意:反转一个单链表。
示例: 输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

迭代实现

  public ListNode reverseList(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }


        ListNode culNode = head;
        ListNode preNode = null;


        while (culNode != null) {
            ListNode nextNode = culNode.next;
            culNode.next = preNode;
            preNode = culNode;
            culNode = nextNode;
        }

        return preNode;
    }

递归实现

 public ListNode reverseList(ListNode head) {
        return reverse(null, head);
    }

    public ListNode reverse(ListNode pre, ListNode cul) {
        if (cul == null) {
            return pre;
        }
        ListNode next = cul.next;
        cul.next = pre;
        return reverse(cul, next);
    }

4.环形链表II
题意:给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。
如果 pos 是 -1,则在该链表中没有环。
「说明」:不允许修改给定的链表。

 //用set
    public ListNode detectCycle(ListNode head) {
        HashSet set = new HashSet();
        while (head != null) {
            if (!set.add(head)) {
                return head;
            }
            head = head.next;
        }
        return null;
    }

    //快慢指针
    public ListNode detectCycle2(ListNode head) {
        ListNode fastIndex = head;
        ListNode slowIndex = head;
        while (fastIndex != null && fastIndex.next != null) {
            fastIndex = fastIndex.next.next;
            slowIndex = slowIndex.next;
            if (fastIndex == slowIndex) {
                fastIndex = head;
                while (fastIndex != slowIndex) {
                    fastIndex = fastIndex.next;
                    slowIndex = slowIndex.next;
                }
                return fastIndex;
            }
        }
        return null;
    }

你可能感兴趣的:(开发人员必须掌握的高频算法题之链表(2))