链表中倒数第k个链表
**题目:**链表中倒数第k个结点
题目链接:OJ链接
示例1
输入:1,{1,2,3,4,5}
返回值:{5}
**题目解析:**要求倒数第k个结点的位置,那么我们只需要找(length - k)的结点位置即可,具体分析如下:
ListNode cur = head;
for(int i = 0; i < count - k; i++){
cur = cur.next;
}
以示例1为例,那么上述代码就变成了这样:
ListNode cur = head;
for(int i = 0; i < 4; i++){
cur = cur.next;
}
当 i = 0 时,执行第一次循环,此时 cur.val = 2,i 自增为 1;
当 i = 1 时,执行第二次循环,此时 cur.val = 3,i 自增为 2;
当 i = 2 时,执行第三次循环,此时 cur.val = 4,i 自增为 3;
当 i = 3 时,执行第四次循环,此时 cur.val = 5,i 自增为 4;
当 i = 4时,不满足条件结束循环,自此循环完成,cur.val = 5;
在上述描述中, val 只是为了方便解析而自加的属性,在代码中只要求结点,并没有要求需要结点的值,望周知!
由此我们可以看出,第(length - k)个结点 = 倒数第k个结点 ,这样就可以顺利地写代码啦!
第一步:求出链表长度
for(ListNode cur = head; cur != null; cur = cur.next){
length++;
}
第二步:求第(length - k)个结点
for(int i = 0; i < length - k; i++){
cur = cur.next;
}
代码实现注意事项:
- 注意链表是否为空,为空直接返回即可,节省时间
- 注意判断k的长度,如果k的长度大于链表长度的话,返回的应该是一个空结点,而由于没有 if 条件的限制,cur 不会进入第二个循环,返回的是头结点;
具体代码:
public class Solution {
public ListNode FindKthToTail(ListNode head, int k) {
//先确定特殊情况
if(head == null){
return null;
}
//先求出其总长度,然后总长度 - k,遍历到这个节点就是倒数第 k 个结点
int length = 0;
for(ListNode cur = head; cur != null; cur = cur.next){
length++;
}
if(k > length){
return null;
}
ListNode cur = head;
for(int i = 0; i < length - k; i++){
cur = cur.next;
}
return cur;
}
}
合并两个有序链表
**题目:**将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
题目链接:OJ链接
示例:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
**题目解析:**题目中有两个字眼是值得注意的——有序,题目不是简单的要求 l1 的 尾结点指向 l2 的头结点,而是要求合并好的链表升序排列。解决方法也简单,l1 和 l2 的结点相互比较,那个结点的值比较小就先指向谁。具体解析如下:
以示例为例子:
if(l1.val == l2.val){
tail.next = l1;
l1 = l1.next;
//更新tail
tail = tail.next;
}else if(l1.val > l2.val){
//小的先进新链表
tail.next = l2;
//更新
l2 = l2.next;
tail = tail.next;
}else{
tail.next = l1;
//更新
l1 = l1.next;
tail = tail.next;
}
首先,建立一个傀儡结点(傀儡结点就是无关紧要的结点,其不具备实际意义),使得 tail = 傀儡结点;
以此类推,直至当两个链表中有一个链表的引用指向空结点为止;
题目注意事项:
- 在比较之前要先判断两个链表之中是否有着空链表,如果有直接返回非空链表;因为如果在比较中出现空链表会报空引用异常
- 循环结束条件为两个链表其中之一的引用指向空结点,否则在比较中也会报空引用异常
- 最后不要忘记处理非空链表
代码实现:
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
//判断特殊情况,即两个有序链表其中有一个是空链表的情况
if(l1 == null){
return l2;
}
if(l2 == null){
return l1;
}
//创建一个新链表来存储,为了方便,创建一个带傀儡结点的链表
ListNode dummy = new ListNode(0);
ListNode tail = dummy;
while(l1 != null && l2 != null){
//判断二者的值是否相等,相等的话就让 l1 先进新链表
if(l1.val == l2.val){
tail.next = l1;
l1 = l1.next;
//更新tail
tail = tail.next;
}else if(l1.val > l2.val){
//小的先进新链表
tail.next = l2;
//更新
l2 = l2.next;
tail = tail.next;
}else{
tail.next = l1;
//更新
l1 = l1.next;
tail = tail.next;
}
}
if(l1 == null){
tail.next = l2;
}else{
tail.next = l1;
}
return dummy.next;
}
}