力扣算法打卡4

21. 合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:
输入:l1 = [], l2 = []
输出:[]
示例 3:
输入:l1 = [], l2 = [0]
输出:[0]
提示:
两个链表的节点数目范围是 [0, 50]
-100 <= Node.val <= 100
l1 和 l2 均按 非递减顺序排列

解题思路:

  1. 定义一个初始化头结点,以及一个尾节点,尾节点初始指向头结点
  2. 当节点1小于节点2时,尾节点的next指向节点1,节点1往后移
  3. 当节点1大于等于节点2时,尾节点的next指向节点2,节点2往后移
  4. 更新尾节点为下一节点
  5. 当节点1或节点2为null时,表示其中一个链表移到结尾了,可将尾节点的next直接指向另一个节点,表示拼接剩余节点
  6. 返回头结点的下一个节点,即拼接后的链表头结点

代码如下:

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
    ListNode head = new ListNode();
    ListNode moveNode = head;
    while (true) {
        if (l1 == null) {
            moveNode.next = l2;
            break;
        }
        if (l2 == null) {
            moveNode.next = l1;
            break;
        }
        if (l1.val < l2.val) {
            moveNode.next = l1;
            l1 = l1.next;
        } else {
            moveNode.next = l2;
            l2 = l2.next;
        }
        moveNode = moveNode.next;
    }
    return head.next;
}

相关数据结构:

public class ListNode {
    public int val;
    public ListNode next;

    public ListNode() {
    }

    public ListNode(int val) {
        this.val = val;
    }

    public ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
}

55. 跳跃游戏

给定一个非负整数数组nums ,你最初位于数组的 第一个下标 。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标。
示例1:
输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3 步到达最后一个下标。
示例2:
输入:nums = [3,2,1,0,4]
输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 ,所以永远不可能到达最后一个下标。
提示:
1 <= nums.length <= 3 * 104
0 <= nums[i] <= 105

解题思路:贪心算法。第n个元素能跳的范围是n~n+nums[n],只要这个范围内存在某个元素,跳跃的最远距离能超过这个范围,则表示第n元素可以借助那个元素跳到更远;如果不存在,并且最远跳跃还没跳到数组最后一个元素,则没必要再跳下去了,直接返回false,因为不存在有效借力点,也就跳不了更远

  1. 统计每个位置能跳到的最远位置,若比原来最远记录更大,则更新最远记录
  2. 若当前位置已经越过了最远位置,表示上一个位置上的元素为0,且之前所有元素都没能跳过元素0这个位置,即该数组无法跳到最后一个下标,直接返回false

代码如下:

public boolean canJump(int[] nums) {
    int max = 0;
    for (int i = 0; i < nums.length; i++) {
        if (i > max) {
            return false;
        }
        max = Math.max(max, nums[i] + i);
    }
    return true;
}

1487. 保证文件名唯一

给你一个长度为 n 的字符串数组 names 。你将会在文件系统中创建 n 个文件夹:在第 i 分钟,新建名为 names[i] 的文件夹。
由于两个文件 不能 共享相同的文件名,因此如果新建文件夹使用的文件名已经被占用,系统会以 (k) 的形式为新文件夹的文件名添加后缀,其中 k 是能保证文件名唯一的 最小正整数 。
返回长度为 n 的字符串数组,其中 ans[i] 是创建第 i 个文件夹时系统分配给该文件夹的实际名称。
示例 1:
输入:names = ["pes","fifa","gta","pes(2019)"]
输出:["pes","fifa","gta","pes(2019)"]
解释:文件系统将会这样创建文件名:
"pes" --> 之前未分配,仍为 "pes"
"fifa" --> 之前未分配,仍为 "fifa"
"gta" --> 之前未分配,仍为 "gta"
"pes(2019)" --> 之前未分配,仍为 "pes(2019)"
示例 2:
输入:names = ["gta","gta(1)","gta","avalon"]
输出:["gta","gta(1)","gta(2)","avalon"]
解释:文件系统将会这样创建文件名:
"gta" --> 之前未分配,仍为 "gta"
"gta(1)" --> 之前未分配,仍为 "gta(1)"
"gta" --> 文件名被占用,系统为该名称添加后缀 (k),由于 "gta(1)" 也被占用,所以 k = 2 。实际创建的文件名为 "gta(2)" 。
"avalon" --> 之前未分配,仍为 "avalon"
示例 3:
输入:names = ["onepiece","onepiece(1)","onepiece(2)","onepiece(3)","onepiece"]
输出:["onepiece","onepiece(1)","onepiece(2)","onepiece(3)","onepiece(4)"]
解释:当创建最后一个文件夹时,最小的正有效 k 为 4 ,文件名变为 "onepiece(4)"。
示例 4:
输入:names = ["wano","wano","wano","wano"]
输出:["wano","wano(1)","wano(2)","wano(3)"]
解释:每次创建文件夹 "wano" 时,只需增加后缀中 k 的值即可。
示例 5:
输入:names = ["kaido","kaido(1)","kaido","kaido(1)"]
输出:["kaido","kaido(1)","kaido(2)","kaido(1)(1)"]
解释:注意,如果含后缀文件名被占用,那么系统也会按规则在名称后添加新的后缀 (k) 。
提示:
1 <= names.length <= 5 * 10^4
1 <= names[i].length <= 20
names[i] 由小写英文字母、数字和/或圆括号组成。

解题思路:

  1. 定义一个map集合,用来存储文件名及其出现次数
  2. 遍历所有文件名,每次通过map拿到文件名出现的次数
  3. 如果出现次数为0,则将文件名以及出现次数1存入map中
  4. 如果出现次数为大于0,则表示文件名出现重复,将文件名拼接上次数之后,再判断这个新文件名是否还存在,若还存在,则次数+1之后再次拼接并再次判断是否存在,这里用while循环来处理
  5. 直到新文件名不再重复后,将新文件名及其出现次数1存入map中,并且更新原文件名出现的次数(原次数+重复的次数)
  6. 每次重命名完就更新当前位置为新文件名

代码如下:

public String[] getFolderNames(String[] names) {
    int length = names.length;
    Map<String, Integer> map = new HashMap<>();
    for (int i = 0; i < length; i++) {
        String name = names[i];
        int count = map.getOrDefault(name, 0);
        String filename = name;
        if (count > 0) {
            while (map.containsKey(filename)) {
                filename = name + "(" + (count++) + ")";
            }
            map.put(name, count);
            map.put(filename, 1);
        } else {
            map.put(name, 1);
        }
        names[i] = filename;
    }
    return names;
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • CD-Python-JY-1809班项目阶段教学内容 开篇 - 就业形势分析 就业方向Python后端开发工程师(...
    ychaochaochao阅读 1,105评论 0赞 1
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 137,313评论 19赞 139
  • 20. 有效的括号 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否...
    Kola_King阅读 374评论 0赞 0
  • File types(文件类型) go命令检查目录中特定文件的集合。它根据文件的扩展名表示要检查的文件。这些扩展名...
    Cxb168阅读 1,928评论 0赞 0
  • 推荐指数: 6.0 书籍主旨关键词:特权、焦点、注意力、语言联想、情景联想 观点: 1.统计学现在叫数据分析,社会...
    Jenaral阅读 6,304评论 0赞 5

友情链接更多精彩内容