【leetcode】147 Insertion Sort List

插入排序

题意

使用插入排序对一个单链表进行排序

思路

说实话,没思路。先看看数组的插入排序吧,也许能找到灵感:

数组插入排序

数组的插入排序,需要对数组进行两重遍历,第一次找到一个比前面数字小的一个数字,说明它需要被移动到前面去,所以再从当前节点开始从后往前遍历,将每一个比其大的数字都往后移一位,直到找到一个比它小的数字,然后插入在这个数字后面,代码如下:

public static void insertSort(int[] array) {
    int len = array.length;
    if(len <= 1)
        return;
    //从第二位开始遍历,找到前一位比后一位大的数字,说明该数字需要被插入到前面去
    for(int i=1;i<len;i++) {
        if(array[i-1] > array[i]) {
        		//临时变量保存array[i]
            int temp = array[i];
            int j=i;
            //从后往前把所有比temp大的数往后移一位
            while (j>0 && array[j-1] > temp) {
                array[j] = array[j-1];
                j--;
            }
            //把temp放在比temp小的数的后面
            array[j] = temp;
        }
    }
    for(int i : array)
        System.out.printf("%d	", i);
}

链表插入排序

到了链表,我们发现一个问题,那就是链表不能从后往前遍历,这就很尴尬了。我本来是尝试找到一个需要移动的节点(即该节点的值比前驱节点的值小),从前往后遍历,直到找到一个节点值比它大时插入到这个节点前面,然而实现了很久发现代码又臭又长,关键是还总有测试用例不通过,最后还是放弃了。

看了答案发现思路应该是创建一个辅助的新链表,并且使用一个指针遍历原链表,每次将原链表中的一个节点插入到新链表的合适位置(即该节点的值大于新链表上的节点的值,又小于后一节点的值)。最后将新链表的头部返回即可。代码如下,做了详细的注释,应该很容易看懂。

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) {
        val = x;
    }
}
/**
 * 链表插入排序
 * */
public ListNode insertionSortList(ListNode head) {
	//边界条件判断
    if(head==null || head.next == null)
        return head;

    //创造一个新的链表头部
    ListNode pre = new ListNode(-1);
    //用一个临时变量保存头节点
    ListNode ans = pre;
    //cur是原链表上的指针
    ListNode cur = head;
    while (cur != null) {
        //每次循环前重置pre为头结点,这样保证每次都从头往后遍历
        pre = ans;
        
        //当pre.next.val大于cur.val时停止循环
        while (pre.next != null && pre.next.val < cur.val) {
            pre = pre.next;
        }

        //pre.next.val 大于 cur.val,此时应该把cur插入到pre后
        //保存原链表当前节点的下一节点
        ListNode tmp = cur.next;
        //把cur插入到pre之后
        cur.next = pre.next;
        pre.next = cur;
        
        //cur指针后移一位
        cur = tmp;
    }
    return ans.next;
}

总结

发现自己做题总是一根筋,直肠子,不知道拐弯,实际上很多题目都不是用常规思维去解的,比如这题就需要一个辅助链表来完成,希望多锻炼能知道更多的套路吧。

原文地址:https://www.cnblogs.com/puyangsky/p/6480942.html