今天是秋招预备队第八天,今天预计写两道题,看能否完成,没完成!!最近变懒了,要加油努力!!
问题1:单链表的排序
描述:
解题方法:
1、辅助数组
1)遍历链表,将链表结点值存入数组
2)将数组中的元素值进行升序排序
3)将数组元素值依次付给链表
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类 the head node
* @return ListNode类
*/
public ListNode sortInList (ListNode head) {
//集合
ArrayList<Integer> lists = new ArrayList<>();
ListNode index = head;
//遍历链表结点
while(index != null){
//将结点值存入集合
lists.add(index.val);
index = index.next;
}
//排序
Collections.sort(lists);
index = head;
//为链表结点重新赋值
for(int list : lists){
index.val = list;
index = index.next;
}
return head;
}
}
2、归并排序(推荐使用)
1)首先判断链表为空或者只有一个元素,直接就是有序的
2)准备三个指针,快指针right每次走两步,慢指针mid每次走一步,前序指针left每次跟在mid前一个位置。三个指针遍历链表,当快指针到达链表尾部的时候,慢指针mid刚好走了链表的一半,正好是中间位置
3)从left位置将链表断开,刚好分成两个子问题开始递归
4)将子问题得到的链表合并
5)最终得到有序链表
import java.util.*;
public class Solution {
//合并两段有序链表
ListNode merge(ListNode pHead1, ListNode pHead2) {
//一个已经为空了,直接返回另一个
if(pHead1 == null)
return pHead2;
if(pHead2 == null)
return pHead1;
//加一个表头
ListNode head = new ListNode(0);
ListNode cur = head;
//两个链表都要不为空
while(pHead1 != null && pHead2 != null){
//取较小值的节点
if(pHead1.val <= pHead2.val){
cur.next = pHead1;
//只移动取值的指针
pHead1 = pHead1.next;
}else{
cur.next = pHead2;
//只移动取值的指针
pHead2 = pHead2.next;
}
//指针后移
cur = cur.next;
}
//哪个链表还有剩,直接连在后面
if(pHead1 != null)
cur.next = pHead1;
else
cur.next = pHead2;
//返回值去掉表头
return head.next;
}
public ListNode sortInList (ListNode head) {
//链表为空或者只有一个元素,直接就是有序的
if(head == null || head.next == null)
return head;
ListNode left = head;
ListNode mid = head.next;
ListNode right = head.next.next;
//右边的指针到达末尾时,中间的指针指向该段链表的中间
while(right != null && right.next != null){
left = left.next;
mid = mid.next;
right = right.next.next;
}
//左边指针指向左段的左右一个节点,从这里断开
left.next = null;
//分成两段排序,合并排好序的两段
return merge(sortInList(head), sortInList(mid));
}
}