面试题12 在一个单向链表中 指定一个元素 x 然后将所有小于 x 的元素都放到 x 左边 剩下的元素放到 x 的右边
题目: 重新组织一个单项链表 指定一个元素 x 然后将 小于 x 的元素置于 x 前面 将大于等于 x 的元素置于 x 的右边
思路: 另设一个链表 将 x 从原链表中取出 放入新链表 然后 遍历原链表将元素取出 如果当前元素小于 x 则加到新链表表头 否则加到新链表尾部
代码如下
public void mySolution(E x){ if(x==null || super.isEmpty()) return; Node<E> node = takeNode(x); if(node==null) return; SinglyLinkedList<E> after = new SinglyLinkedList<E>(); after.addLast(node.data()); while(!super.isEmpty()){ E cur = super.poll(); if(cur.compareTo(x)<0){ after.addFirst(cur); }else{ after.addLast(cur); } } super.setHead(after.findFirst()); super.setSize(after.size()); } private Node<E> takeNode(E data){ if(isEmpty() || data==null) return null; Node<E> result; Node<E> current = super.findFirst(); if(current.data().equals(data)){ result = current; super.setHead(current.next()); super.decreaseSize(); return result; }else{ while(current.next()!=null){ if(current.next().data().equals(data)){ result = current.next(); current.setNext(current.next().next()); super.decreaseSize(); result.setNext(null); return result; } current = current.next(); } return null; } }
该方法 不需要额外空间 空间复杂度是 O(1) 而时间复杂度取决于 x 的选择 最坏情况下需要 O(n^2) 的时间复杂度 如果单向链表本身维持一个 tail 指针指向尾部 则时间复杂度可以提升到 O(n)
维持尾部元素的代码如下
public void goodSolution(E x){ if(x==null || super.size()<2) return; Node<E> head = super.findFirst(); Node<E> tail = super.findFirst(); Node<E> current = super.findFirst(); while(current!=null){ Node<E> next = current.next(); if(current.data().compareTo(x)<0){ current.setNext(head); head = current; }else{ tail.setNext(current); tail = current; } current = next; } tail.setNext(null); super.setHead(head); }
该方法空间复杂度依然是 O(1) 而时间复杂度提升到了 O(n) 是最优解