力扣hot100【Day4】

文章目录

  • 12. 罗马数字转整数
  • 14. 最长公共前缀
  • 15. 三数之和
    • 解法
  • 16. 最接近的三数之和
    • 解法
  • 17. 电话号码的字母组合
    • 解法
  • 18. 四数之和
    • 解法
  • 19.删除链表的倒数第N个结点
    • 解法
  • 20. 有效的括号
    • 解法
  • 21. 合并两个有序链表
    • 解法
  • 22. 括号生成
  • 23. 合并k个升序链表
    • 解法
  • 24. 两两交换链表中的结点
    • 解法
  • 25. K个一组反转列表
    • 解法
  • 26. 删除有序数组中的重复项
    • 解法
  • 27. 移除元素
    • 解法
  • 28. 实现strStr()
    • 解法
    • 解法
  • 29.两数相除
    • 解法
  • 30. 串联所有单词的子串
    • 解法


12. 罗马数字转整数

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。

字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。
力扣hot100【Day4】_第1张图片
力扣hot100【Day4】_第2张图片

  • 整数转罗马数字需要考虑先把最大部分的分离出来,因此定义了两个数组,按顺序遍历;罗马数字转整数罗马数字本身已经有顺序,直接确定映射即可,因此定义了一个map
  • map list set 结构的初始化可以采用双大括号的形式
  • 只要当前符号表示的数小于后一个符号表示的数,则该数应被减掉,其余情况全部相加即可

14. 最长公共前缀

编写一个函数来查找字符串数组中的最长公共前缀。

如果不存在公共前缀,返回空字符串 “”。

力扣hot100【Day4】_第3张图片
力扣hot100【Day4】_第4张图片

  • 先将第一个String赋值给最终结果ans,然后依次遍历剩余String,比较第一个String和其余String的每一个字符,获取一个新的ans,继续与另外的String比较

15. 三数之和

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。
力扣hot100【Day4】_第5张图片

解法

力扣hot100【Day4】_第6张图片

  • 先将所有数排序,然后设置双指针从两侧开始遍历,寻找和为0的组合
  • 如果数组长度小于3或数组为空,直接返回空
  • 如果数组的最小值大于0则返回空
  • 一般情况下,如果当前值与上一个值相等,则跳过(去重);当和为0的时候,指针left和right需要移动到发生变化的数(去重);当和小于0,则左指针右移;当和大于0,则右指针左移
  • 数组升序排序 Arrays.sort(nums)
  • 数组转成列表 Arrays.asList(nums[2], nums[3])

16. 最接近的三数之和

给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。

返回这三个数的和。

假定每组输入只存在恰好一个解。

力扣hot100【Day4】_第7张图片

解法

力扣hot100【Day4】_第8张图片

  • 先对数组排序
  • 从小到大依次遍历数组中的每一个元素
  • 赋值left = i + 1 right = length - 1
  • 在满足left小于right的前提下,判断和 - target的绝对值和ans - target的绝对值之间的关系
  • 如何移动指针:当前和小于目标值,则左指针右移,当前和大于目标值则右指针左移,当前和等于目标值则直接返回target’

17. 电话号码的字母组合

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母

力扣hot100【Day4】_第9张图片
力扣hot100【Day4】_第10张图片

解法

力扣hot100【Day4】_第11张图片

力扣hot100【Day4】_第12张图片

  • String s = null 表示s不占用内存空间,也没有任何属性,没有.length属性
  • String s = “” 表示s指向一个长度为0的字符串,占内存空间
  • StringBuffer类可以修改String,转化为String类型为ans.toString(); 删除某一个元素为ans.deleteCharAt(index);

18. 四数之和

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):

0 <= a, b, c, d < n
a、b、c 和 d 互不相同
nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
力扣hot100【Day4】_第13张图片

解法

力扣hot100【Day4】_第14张图片

  • 四数之和类似于三数之和,三数之和是一个for循环加两个双指针,四数之和是两个for循环加两个双指针
  • 先对数组排序
  • 防止重复,既要在 i 和 j 的选择上防止重复,也要在left和right两个指针上防止重复
  • 考虑溢出,int型会发生溢出,则将其中被加数转化成long型,则最终结果为long型

19.删除链表的倒数第N个结点

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
力扣hot100【Day4】_第15张图片

解法

力扣hot100【Day4】_第16张图片

  • java中没有指针
  • 先确定好两个指针的位置间隔,其中一个指向最后一个结点,另一个指向待删除结点的前一个结点。间隔确定好以后两个指针开始同时移动至后指针达到最后结点

20. 有效的括号

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。

力扣hot100【Day4】_第17张图片

解法

力扣hot100【Day4】_第18张图片

  • 定义一个LinkedList当作栈使用,addLast removeLast
  • removeLast函数删除最后一个元素且返回最后一个元素,当list为空时会报错,因此需要在栈中添加一个?元素
  • 遇到左括号加到栈中,遇到右括号则弹出栈中元素判断是否匹配,若不匹配直接返回false,提前结束

21. 合并两个有序链表

将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
力扣hot100【Day4】_第19张图片

解法

力扣hot100【Day4】_第20张图片

  • 依次遍历两个链表
  • 定义一个头指针,用于返回值

22. 括号生成

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
力扣hot100【Day4】_第21张图片
力扣hot100【Day4】_第22张图片

  • 采用回溯法解决

23. 合并k个升序链表

给你一个链表数组,每个链表都已经按升序排列。

请你将所有链表合并到一个升序链表中,返回合并后的链表。

力扣hot100【Day4】_第23张图片

解法

力扣hot100【Day4】_第24张图片

  • 依次顺序合并,以合并两个链表为基础

24. 两两交换链表中的结点

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
力扣hot100【Day4】_第25张图片

解法

力扣hot100【Day4】_第26张图片

  • 利用三步完成两节点顺序交换
  • 设置一个哑结点,每次交换的是哑结点后面的两个结点
  • 当哑结点后面的元素个数少于2时,则不够交换,直接结束

25. K个一组反转列表

给你链表的头节点 head ,每 k 个节点一组进行翻转,请你返回修改后的链表。

k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

力扣hot100【Day4】_第27张图片
力扣hot100【Day4】_第28张图片

解法

力扣hot100【Day4】_第29张图片

  • 分成多个反转长度为k的链表

26. 删除有序数组中的重复项

给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。

由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。

将最终结果插入 nums 的前 k 个位置后返回 k 。

不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
力扣hot100【Day4】_第30张图片
力扣hot100【Day4】_第31张图片

解法

力扣hot100【Day4】_第32张图片

  • 设置两个指针,slow指向待插入的位置,fast指向待检查的数据,依次覆盖即可

27. 移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:
力扣hot100【Day4】_第33张图片
力扣hot100【Day4】_第34张图片

解法

力扣hot100【Day4】_第35张图片

  • 设置两个指针slow和fast,一个指向待插入位置,另一个指向待检查元素

28. 实现strStr()

实现 strStr() 函数。

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。

说明:

当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。

对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。
力扣hot100【Day4】_第36张图片

解法

力扣hot100【Day4】_第37张图片

解法

暴力破解

  • 不必当haystack的指针移动最后一个元素就可以停止循环
  • 需要设置一个flag,一旦不匹配则跳出最内层循环

29.两数相除

给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。

返回被除数 dividend 除以除数 divisor 得到的商。

整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2

力扣hot100【Day4】_第38张图片

解法

力扣hot100【Day4】_第39张图片

  • 先确定符号,然后全部转化成负数后运算
  • 除法可以看作多步减法

30. 串联所有单词的子串

给定一个字符串 s 和一些 长度相同 的单词 words 。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。

注意子串要与 words 中的单词完全匹配,中间不能有其他字符 ,但不需要考虑 words 中单词串联的顺序。
力扣hot100【Day4】_第40张图片

解法

力扣hot100【Day4】_第41张图片

  • 将所有被串连单词放到hashmap中,记录每个单词出现次数
  • 在主串中,每次截取被串连单词长度的字符串,将其也放入hashmap中,比较两个map是否完全相等
  • 利用map记录单词出现次数可以使用map.put(key, map.getOrDefault(key, 默认值)+1),若map中没有key值,getOrDefault可以返回指定值

你可能感兴趣的:(leetcode,算法,java)