08-02-反转链表Ⅰ、Ⅱ,删除排序链表中的重复元素

举报
一条coding 发表于 2022/08/29 23:26:18 2022/08/29
【摘要】 每日三刷,剑指千题 计划简介: 每日三题,以中等题为主,简单题为辅进行搭配。保证质量题1道,数量题3道。每日早通勤在LeetCode手机端选题,思考思路,没答案的直接看题解。每日中午进行编码,...

每日三刷,剑指千题

计划简介:

  • 每日三题,以中等题为主,简单题为辅进行搭配。保证质量题1道,数量题3道。
  • 每日早通勤在LeetCode手机端选题,思考思路,没答案的直接看题解。
  • 每日中午进行编码,时间控制在一小时之内。
  • 下班前半小时进行整理总结,并发布到掘金每日更文活动。

说明:

  • 基于以前的刷题基础,本次计划以中等题为主,大部分中等题都可以拆分为多个简单题,所以数量保证3,质量保证一道中等题即可。
  • 刷题顺序按照先刷链表、二叉树、栈、堆、队列等基本数据结构,再刷递归、二分法、排序、双指针等基础算法,最后是动态规划、贪心、回溯、搜索等复杂算法。
  • 刷题过程中整理相似题型,刷题模板。
  • 目前进度 109/1000

[剑指 Offer 24]反转链表

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

  
 
  • 1
  • 2

限制:

0 <= 节点个数 <= 5000

  
 
  • 1

注意:本题与主站 206 题相同:https://leetcode-cn.com/problems/reverse-linked-list/

解析

这里讲的是迭代法,按我的思路去记,绝对不会忘。

首先需要有一个答案链表,我们要维护一个这个链表的尾指针,作什么呢?

我们从原链表上拆下来一个,使其下一个指向尾指针。

同时尾指针下移,当前结点下移,去拆下一个。

Code

public ListNode reverseList(ListNode head) {
        ListNode cur = head;
        ListNode ans = null;
        while (cur!=null){
            ListNode next = cur.next;
            // 核心 拆下里的结点指向尾指针
            cur.next = ans;
            // 尾指针下移
            ans = cur;
            // 结点向下遍历
            cur = next;
        }
        return ans;
    }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

[92]反转链表 II

给你单链表的头指针 head 和两个整数 leftright ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表

示例 1:

img

输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]

  
 
  • 1
  • 2

解析

这题和反转链表1相比,改了起点和终点,那笨方法,先把需要的部分拆下来,反转完再拼回去不就行了。但是,

进阶: 你可以使用一趟扫描完成反转吗?

怎么搞?

Code

先用笨方法写一遍吧,代码有点多,但效率还是可以的。

image-20220802133525788

class Solution {
    public ListNode reverseBetween(ListNode head, int left, int right) {
        if (head == null)return null;
        if (left == right) return head;
        int times = right - left + 1;
        ListNode prev  = head;
        for (int i = 1; i < left -1 ; i++) {
            prev =prev.next;
        }
        if (left!=1){
            prev.next = reverseList(prev.next,times);
            return head;
        }else {
            return reverseList(prev,times);
        }
    }
    private ListNode reverseList(ListNode head,int times) {
        ListNode cur = head;
        ListNode ans = null;
        int flag = 0;
        while (flag < times){
            ListNode next = cur.next;
            // 核心 拆下里的结点指向尾指针
            cur.next = ans;
            // 尾指针下移
            ans = cur;
            // 结点向下遍历
            cur = next;
            flag ++;
        }
        ListNode tail = ans;
        while (ans.next!=null){
            ans = ans.next;
        }
        ans.next = cur;
        return tail;
    }
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

[83]删除排序链表中的重复元素

给定一个已排序的链表的头 head删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表

示例 1:

img

输入:head = [1,1,2]
输出:[1,2]

  
 
  • 1
  • 2

解析

其实回过头一想,还是双指针的思想。或者也可以理解成滑动窗口,连续的重复结点就是一个不断变化的窗口。

那双指针,一个指针指向前一个结点,一个指针向下遍历。

思想简单,但编码实现上还是要考虑一下边界值及具体逻辑。

Code

 class Solution {
        // 题目数据保证链表已经按升序 排列
        public ListNode deleteDuplicates(ListNode head) {
            // 特例返回
            if (head==null) return null;
            // 虚拟头结点,只是返回用
            ListNode dummy = new ListNode(0, head);
            // 第一个初始值
            int init = head.val;
            // 遍历迭代
            while (head.next != null) {
                // 保存上一个结点
                ListNode prev = head;
                // head 指向下一个结点
                head = head.next;
                // 下一个的值和上一个比较
                if (head.val == init) {
                    // 删除下一个结点
                    prev.next = head.next;
                    // 头结点指回到上一个 对应下次的 head = head.next;
                    head =prev;
                } else {
                    // 不相同,那对比值移到下一个
                    init = head.val;
                }
            }
            return dummy.next;
        }
    }

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

=prev;
} else {
// 不相同,那对比值移到下一个
init = head.val;
}
}
return dummy.next;
}
}



  
 
  • 1

文章来源: blog.csdn.net,作者:一条coding,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/skylibiao/article/details/126584371

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。