1.<tag-排序和数组, 链表>-lt.215-数组中的第K个最大元素 + lt.148-排序链表(待完善)
lt.215-数组中的第K个最大元素
[案例需求]
 
[思路分析]
- 本题出现频率非常的高!!!
- 数组中的第K最大, 最小, 或者说中位数, 都可以用各种排序方法先对数组排序, 然后返回要求的值即可;
- 所以嘛, 熟练掌握快排(迭代的, 递归的), 堆排序, 归并排序(迭代的, 递归的)非常有必要!!!, 当然了链表的各种快排, 归并排序也是必要的, 就在下面一道题.
具体的解析和详细代码可看笔者之前的一篇文章: 点我
[效率比较]

lt.148-排序链表
[案例需求]
 
 [思路分析一, 优先队列]
-  有没有这么一种神奇的数据结构, 它能够存入一些数据, 在拿出来的时候这些数据就是有序的了, 他肯定是一种集合容器; 
-  目前最常用的通过匿名内部类的方式添加比较器对象的, 其实也就TreeSet和PriorityQueue两种, 但是TreeSet会自动的对存入的数据去重, 而PriorityQueue就可以存入重复的数据. 
  
-  本题我们采用优先队列 PriorityQueue, 为什么用这个? 
- 可以通过类构造器传入自定义比较器, 但是TreeSet 也可以呀!
- 可以存入重复元素, 哈哈, TreeSet就不行啦!
/**
 * 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 sortList(ListNode head) {
        //排序链表
        //4-->2-->1-->3
        //优先队列
        
        if(head == null)return null;
        PriorityQueue<ListNode> queue = new PriorityQueue<>(new Comparator<ListNode>(){
            public int compare(ListNode node1, ListNode node2){
                return node1.val - node2.val;
            }
        });
        //遍历链表, 放入优先队列;
        ListNode temp = head;
        while(true){
            if(temp == null)break;
        
            queue.add(temp);
            temp = temp.next;
        }
        ListNode dummyNode = new ListNode(-1);
        ListNode temp1 = dummyNode;
        while(queue.size() != 0){
            ListNode node = queue.poll();
            node.next = null; //取出结点, 并断开结点的next域
            temp1.next = node;
            temp1 = temp1.next;
        }
        return dummyNode.next;
    }
}
[思路分析二, 单链表的快速排序]
链表快排!!! 也是相当的重要啦!
[思路分析三, 单链表的归并排序]

/**
 * 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 sortList(ListNode head) {
        if (head == null) {
            return null;
        }
        ListNode mid = getMid(head);
        if (mid.next == null) {
            return mid;
        }
        ListNode headB = mid.next;
        mid.next = null;
        return mergeTwoList(sortList(head), sortList(headB));
    }
    public ListNode getMid(ListNode head) {
        head = new ListNode(0, head);
        ListNode slow = head;
        ListNode fast = head;
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        return slow;
    }
    public ListNode mergeTwoList(ListNode l1, ListNode l2) {
        ListNode dump = new ListNode();
        ListNode last = dump;
        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                last.next = l1;
                l1 = l1.next;
            } else {
                last.next = l2;
                l2 = l2.next;
            }
            last = last.next;
        }
        if (l1 != null) {
            last.next = l1;
        }
        if (l2 != null) {
            last.next = l2;
        }
        return dump.next;
    }
}
[复杂度分析]
 N为链表的长度, 时间复杂度为O(NlogN), 空间复杂度为O(logN)
这道题考察的点很多,有链表归并,有获取链表的中间节点等等,每一个考点都可以作为一道题来进行考察。
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号