目标
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
思路
1.链表的第一解决方案就是递归,返回当前两个链表合并之后的头节点(每一层都返回排序好的链表头,就是永远是第一个的那个节点) 推荐此方法
public function mergeTwoLists($list1,$list2)
{
if ($list1 === null) return $list2;
if ($list2 === null) return $list1;
if ($list1->val < $list2->val){
$list1->next = $this->mergeTwoLists($list1->next, $list2);
return $list1;
} else {
$list2->next = $this->mergeTwoLists($list1, $list2->next);
return $list2;
}
}
2.迭代法,不推荐
public function mergeTwoLists1($list1,$list2)
{
$dummyHead = new ListNode();//这个永远都会指向链表头部
$cur = $dummyHead;//防止指针移动到最后一位无法操作数据
while($list1 !== null && $list2 !== null){
if ($list1->val <= $list2->val){
$cur->next = $list1;
$list1 = $list1->next;
} else {
$cur->next = $list2;
$list2 = $list2->next;
}
$cur = $cur->next;
}
if ($list1 !== null) {
$cur->next = $list1;//list1在while里面已经重新赋值过了
} elseif ($list2 !== null){
$cur->next = $list2;//list2在while里面已经重新赋值过了
}
return $dummyHead->next;
}
public function abc()
{
$list1=[1,2,4];
$list2=[1,3,4];
$list1=init($list1);
$list2=init($list2);
$res = $this->mergeTwoLists1($list1,$list2);
halt($res);
}
/**
* 初始化链表
* @param array $data 链表中要保存的数据,这里以数组为参考
* @return LinkedList 链表数据
*/
function init(array $data)
{
// 初始化 一般会让第一个结点不包含任何数据,仅仅是做为一个空的结点来指向第一个有数据的结点
$list = createLinkedList($data);
$r = $list;
foreach ($data as $key => $value) {
$link = new LinkedList();
$link->val = $value;
$link->next = null;
$r->next = $link;
$r = $link;
}
return $list;
}
/**
* 生成链表
*/
function createLinkedList($data)
{
$list = new LinkedList();
$list->val = null;
$list->next = null;
return $list;
}
扩展
//链表与数组的不同: //1.规定好数组(可储存的字节)之后,多出来的字节就必须从内存新申请一个数组来容纳全部字节。而链表则是随机分散在内存里面,链表只知道自己存放的数据和自己的下一个数据是谁,链表的节点可以是离散的 //2.数组只要知道数组下标之后,可以直接得到自己想要的数据,而链表却需要一个一个数下去才知道对应的节点数据
