0
点赞
收藏
分享

微信扫一扫

【迎战蓝桥】 算法·每日一题(详解+多解)-- day3

1kesou 2022-04-16 阅读 30

🤞目录🤞

💖1. 链表中倒数第k个结点

💖2. 反转链表(五种解题思路)

💖3. 合并两个排序的链表


【大家好,我是爱干饭的猿,如果喜欢这篇文章,点个赞👍,关注一下吧,后续会一直分享题目与算法思路

🥝1. 链表中倒数第k个结点

    // 遍历数组
public ListNode FindKthToTail1(ListNode head,int k) {
if(head == null){
return null;
}
// 记录节点总数
int count = 0;
for(ListNode x = head ; x != null;x = x.next){
count ++;
}
// 如果节点总数小于k ,说明不存在该节点
if(count < k){
return null;
}
// 找到倒数第k 个节点,(找到第(n-k)个节点)
for(int i = 0;i < count - k;i ++){
head = head.next;
}
return head;
}
    // 前后指针法
public ListNode FindKthToTail2(ListNode head,int k) {
if(head == null){
return null;
}
// 前后指针
ListNode first = head;
ListNode second = head;
// 先让前指针走k 步
while(k > 0 && first != null){
first = first.next;
k--;
}
// 然后前后指针一起向后走,当前指针走到末尾,后指针刚好走到倒数第 k的位置
while(first != null){
first = first.next;
second = second.next;
}
// 程序走到这一步
// 如果k>0,说明k大于节点总数,不存在该节点
return k > 0 ? null : second;
}

🥝2. 反转链表(五种解题思路)

        // 头插1(new 新节点)
public ListNode ReverseList1(ListNode head) {
if(head==null|| head.next==null){
return head;
}
ListNode dummyHead = new ListNode(-1);
while(head != null){
// 创建一个节点存当前head的值
ListNode cur = new ListNode(head.val);
// 头插
cur.next = dummyHead.next;
dummyHead.next = cur;

head = head.next;
}
return dummyHead.next;
}
        // 头插2(不用new 空间复杂度O1)
public ListNode ReverseList1_2(ListNode head) {
if(head==null|| head.next==null){
return head;
}
ListNode newNode = null;
while(head != null){
ListNode pre = head;
head = head.next;

//再将p标识的节点头查到新链表
pre.next = newNode;
newNode = pre;
}
return newNode;
}
        // 原地移动(双指针)和 头插2类似
public ListNode ReverseList2(ListNode head) {
if(head == null || head.next == null){
return head;
}

ListNode prev = null;
// 当前需要处理的节点(需要反转)
ListNode cur = head;
while (cur != null){
// 存储cur之后的链
ListNode node = cur.next;
// 原地移动,(改变next指向)
cur.next = prev;
prev = cur;

cur = node;
}
return prev;
}
        // 原地移动(三指针)
public ListNode ReverseList3(ListNode head) {
if(head == null || head.next == null){
return head;
}

ListNode left = head;
ListNode mid = left.next;
ListNode right = mid.next;
// 反转中间节点,但是当right 为 null时,最后一个节点没有处理
while (right != null){
mid.next = left;

left = mid;
mid = right;
right = right.next;
}
// 处理最后一个节点 || 当链表只有两个节点时
mid.next = left;
head.next = null;

return mid;
}
        // 递归写法
public ListNode ReverseList4(ListNode head) {
if(head == null || head.next == null){
return head;
}

ListNode second = head.next;
// 反转第二个节点之后的子链表
ListNode newHead = ReverseList4(head.next);

// 反转链表(每次递归都只是处理second节点前后指向)
second.next = head;
head.next = null;
return newHead;
}

🥝3. 合并两个排序的链表

    // 方法一
public ListNode Merge(ListNode list1,ListNode list2) {
if(list1 == null){
return list2;
}
if(list2 == null){
return list1;
}

ListNode dummyNode = new ListNode(-1);
// 定义一个last节点,指向新链表的末节点位置
ListNode last = dummyNode;
while(list1 != null && list2 != null){
if(list1.val < list2.val){
// 将list1节点 接在last 后
last.next = list1;
// 更新末尾节点位置
last = list1;
// 头结点后移一位
list1 = list1.next;
}else {
// 将list2节点 接在last 后
last.next =list2;
// 更新末尾节点位置
last = list2;
// 头结点后移一位
list2 = list2.next;
}
}

if(list1 == null){
//如果list1 空了,直接接list2链
last.next = list2;
}
if(list2 == null){
//如果list2 空了,直接接list1链
last.next = list1;
}
return dummyNode.next;
}
    // 递归
public ListNode Merge2(ListNode list1,ListNode list2) {
if(list1 == null){
return list2;
}
if(list2 == null){
return list1;
}

if(list1.val < list2.val){
list1.next = Merge2(list1.next,list2);
// 如果list1.val < list2.val,list2头结点之后就接list1
return list1;
}else {
list2.next = Merge2(list1,list2.next);
// 反之,list1头结点就接list2
return list2;
}
}
举报

相关推荐

0 条评论