目录
445.两数相加 II
给定两个非空链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储单个数字。将这两数相加会返回一个新的链表。
你可以假设除了数字 0 之外,这两个数字都不会以零开头。
进阶:
如果输入链表不能修改该如何处理?换句话说,你不能对列表中的节点进行翻转。
示例:
输入: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4) 输出: 7 -> 8 -> 0 -> 7
与LeetCode2. 两数相加题目类似,2号题链表已倒序排好,仅考虑进位标志即可
445是正序的链表,题目要求链表不能修改,因此可以采用辅助的数据结构
解法:1.遍历两个链表,将链表的值存储在辅助数据结构栈中 2.进行类似大数相加的加法过程
class Solution {
function addTwoNumbers($l1, $l2) {
//借助栈的数据结构
$num1 = $num2 = [];
//压栈过程
while ($l1) {
array_unshift($num1, $l1->val);
$l1 = $l1->next;
}
while ($l2) {
array_unshift($num2, $l2->val);
$l2 = $l2->next;
}
$flag = 0; //进位标识符
$len = max(count($num1),count($num2));
//初始化结果链表头节点,出栈加法过程
$preNode = null;
for($i = 0;$i<$len;++$i){
$add1 = $num1[$i] ? $num1[$i]:0;
$add2 = $num2[$i] ? $num2[$i]:0;
$sum = $add1 + $add2 + $flag;
if($sum>=10){
$flag = 1;
$sum -= 10;
}else{
$flag = 0;
}
//从后往前的链表构建过程
$curNode = new ListNode($sum);
$curNode->next = $preNode;
$preNode = $curNode;
}
if($flag == 1){
$curNode = new ListNode(1);
$curNode->next = $preNode;
}
return $curNode;
}
}
328. 奇偶链表
给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。
请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。
示例 1:
输入: 1->2->3->4->5->NULL 输出: 1->3->5->2->4->NULL示例 2:
输入: 2->1->3->5->6->4->7->NULL 输出: 2->3->6->7->1->5->4->NULL说明:
- 应当保持奇数节点和偶数节点的相对顺序。
- 链表的第一个节点视为奇数节点,第二个节点视为偶数节点,以此类推。
解析:奇偶性指的值节点位置,而不是节点的值
解法:1.构建双指针,一个指向奇节点,一个指向偶节点 2.遍历链表 3.将奇偶节点连接起来
class Solution {
function oddEvenList($head) {
if($head == null || $head->next == null){
return $head;
}
//初始化奇偶节点
$oddNode = $head;
$evenFirstNode = $evenNode = $head->next; //第一个偶节点
//遍历链表
while ($oddNode->next != null && $evenNode->next != null) {
$oddNode->next = $evenNode->next; //偶节点的下一节点是奇节点
$oddNode = $oddNode->next; //取新的奇节点
$evenNode->next = $oddNode->next; //新的奇节点的下一节点是新的偶节点
$evenNode = $evenNode->next; //取新的偶节点
}
//连接奇偶节点
$oddNode->next = $evenFirstNode;
return $head;
}
}
86. 分隔链表
给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。
你应当保留两个分区中每个节点的初始相对位置。
示例:
输入: head = 1->4->3->2->5->2, x = 3 输出: 1->2->2->4->3->5
解析:与快排的partition类似,解法也与快排类似
解法:1.构建大小指针 2.遍历链表 3.连接大小指针
class Solution {
function partition($head, $x) {
$curNode = $head;
$smallNode = $bigNode = $bigFirstNode = null; //构建大小指针
while ($curNode) {
//属于小的一侧
if($curNode->val < $x){
if(is_null($smallNode)){ //初始化小节点
$smallNode = $curNode;
$head = $smallNode;
}else{
$smallNode->next = $curNode;//找到下一个小的节点
$smallNode = $curNode;
}
}else{
//属于大的一侧
if(is_null($bigNode)){ //初始化大节点
$bigNode = $curNode;
$bigFirstNode = $bigNode; //大的一侧的第一个节点
}else{
$bigNode->next = $curNode; //找到下一个小的节点
$bigNode = $curNode;
}
}
$curNode = $curNode->next;
}
$smallNode->next = $bigFirstNode; //大小侧的连接
$bigNode->next = null; //封闭尾节点
return $head;
}
}