56. 合并区间,57. 插入区间,58. 最后一个单词的长度,每题做详细思路梳理,配套Python&Java双语代码, 2024.03.20 可通过leetcode所有测试用例。
目录
56. 合并区间
解题思路
完整代码
Python
Java
编辑
57. 插入区间
解题思路
完整代码
Python
Java
58. 最后一个单词的长度
解题思路
完整代码
Python
Java
56. 合并区间
以数组
intervals
表示若干个区间的集合,其中单个区间为intervals[i] = [starti, endi]
。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。示例 1:
输入:intervals = [[1,3],[2,6],[8,10],[15,18]] 输出:[[1,6],[8,10],[15,18]] 解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].示例 2:
输入:intervals = [[1,4],[4,5]] 输出:[[1,5]] 解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
解题思路
- 排序:首先按照每个区间的起始位置对所有区间进行排序,这样可以保证我们在处理区间时是按照顺序来的,便于合并。
- 合并区间:初始化一个空的结果数组,然后遍历排序后的区间。对于每个区间,如果结果数组为空或者当前区间的起始位置大于结果数组中最后一个区间的结束位置,就直接将当前区间添加到结果数组中。否则,如果当前区间与结果数组中最后一个区间有重叠(即当前区间的起始位置小于等于结果数组中最后一个区间的结束位置),就将结果数组中最后一个区间的结束位置更新为当前区间的结束位置和结果数组中最后一个区间的结束位置中的较大者。
完整代码
Python
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
intervals.sort(key=lambda x: x[0]) # Step 1: Sort the intervals by their start values
merged = []
for interval in intervals:
# Step 2: If the list of merged intervals is empty or if the current
# interval does not overlap with the previous, simply append it.
if not merged or merged[-1][1] < interval[0]:
merged.append(interval)
else:
# Otherwise, there is overlap, so we merge the current and previous intervals.
merged[-1][1] = max(merged[-1][1], interval[1])
return merged
Java
public class Solution {
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0])); // Step 1: Sort the intervals by their start values
LinkedList<int[]> merged = new LinkedList<>();
for (int[] interval : intervals) {
// Step 2: If the list of merged intervals is empty or if the current
// interval does not overlap with the previous, simply add it.
if (merged.isEmpty() || merged.getLast()[1] < interval[0]) {
merged.add(interval);
} else {
// Otherwise, there is overlap, so we merge the current and previous intervals.
merged.getLast()[1] = Math.max(merged.getLast()[1], interval[1]);
}
}
return merged.toArray(new int[merged.size()][]);
}
}
57. 插入区间
给你一个 无重叠的 ,按照区间起始端点排序的区间列表
intervals
,其中intervals[i] = [starti, endi]
表示第i
个区间的开始和结束,并且intervals
按照starti
升序排列。同样给定一个区间newInterval = [start, end]
表示另一个区间的开始和结束。在
intervals
中插入区间newInterval
,使得intervals
依然按照starti
升序排列,且区间之间不重叠(如果有必要的话,可以合并区间)。返回插入之后的
intervals
。注意 你不需要原地修改
intervals
。你可以创建一个新数组然后返回它。示例 1:
输入:intervals = [[1,3],[6,9]], newInterval = [2,5] 输出:[[1,5],[6,9]]示例 2:
输入:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] 输出:[[1,2],[3,10],[12,16]] 解释:这是因为新的区间[4,8]
与[3,5],[6,7],[8,10]
重叠。
解题思路
要在已经排序且无重叠的区间列表中插入一个新的区间,并且仍然保持列表的有序性与不重叠性,可以采取以下步骤:
- 初始化:创建一个空的列表
result
来存储最终的区间列表。 - 添加新区间前的区间:遍历原始区间列表,将所有结束位置小于新区间起始位置的区间添加到
result
中,因为这些区间与新区间不重叠,并且在新区间的左侧。 - 合并重叠区间:继续遍历,对于每个与新区间重叠的区间(即区间的起始位置小于等于新区间的结束位置),更新新区间的起始和结束位置,使其扩展到包括当前区间。这一步可能会通过多次迭代来合并多个重叠的区间。
- 添加合并后的新区间:将更新后的新区间添加到
result
中。 - 添加新区间后的区间:最后,将所有起始位置大于新区间结束位置的区间添加到
result
中,因为这些区间与新区间不重叠,并且在新区间的右侧。
完整代码
Python
class Solution:
def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]:
result, i = [], 0
# Step 2: Add all intervals before the newInterval
while i < len(intervals) and intervals[i][1] < newInterval[0]:
result.append(intervals[i])
i += 1
# Step 3: Merge all overlapping intervals to one considering newInterval
while i < len(intervals) and intervals[i][0] <= newInterval[1]:
newInterval[0] = min(newInterval[0], intervals[i][0])
newInterval[1] = max(newInterval[1], intervals[i][1])
i += 1
result.append(newInterval) # Step 4: Add the merged interval
# Step 5: Add the rest of the intervals
while i < len(intervals):
result.append(intervals[i])
i += 1
return result
Java
public class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
List<int[]> result = new ArrayList<>();
int i = 0;
// Step 2: Add all intervals before the newInterval
while (i < intervals.length && intervals[i][1] < newInterval[0]) {
result.add(intervals[i]);
i++;
}
// Step 3: Merge all overlapping intervals to one considering newInterval
while (i < intervals.length && intervals[i][0] <= newInterval[1]) {
newInterval[0] = Math.min(newInterval[0], intervals[i][0]);
newInterval[1] = Math.max(newInterval[1], intervals[i][1]);
i++;
}
result.add(newInterval); // Step 4: Add the merged interval
// Step 5: Add the rest of the intervals
while (i < intervals.length) {
result.add(intervals[i]);
i++;
}
return result.toArray(new int[result.size()][]);
}
}
58. 最后一个单词的长度
给你一个字符串
s
,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。单词 是指仅由字母组成、不包含任何空格字符的最大
子字符串
。示例 1:
输入:s = "Hello World" 输出:5 解释:最后一个单词是“World”,长度为5。示例 2:
输入:s = " fly me to the moon " 输出:4 解释:最后一个单词是“moon”,长度为4。示例 3:
输入:s = "luffy is still joyboy" 输出:6 解释:最后一个单词是长度为6的“joyboy”。
解题思路
- 去除尾部空格:首先,我们需要从字符串的尾部开始去除所有的空格,以确保当我们从字符串末尾开始查找单词时,不会被尾部的空格干扰。
- 查找最后一个单词:在去除尾部空格后,我们从字符串的最后一个字符开始向前遍历,直到遇到空格或到达字符串的开头。这个过程中遍历的字符数量就是最后一个单词的长度。
完整代码
Python
class Solution:
def lengthOfLastWord(self, s: str) -> int:
length = 0
# Step 1: Trim the trailing spaces
index = len(s) - 1
while index >= 0 and s[index] == ' ':
index -= 1
# Step 2: Count the length of the last word
while index >= 0 and s[index] != ' ':
length += 1
index -= 1
return length
Java
public class Solution {
public int lengthOfLastWord(String s) {
int length = 0;
int index = s.length() - 1;
// Step 1: Trim the trailing spaces
while (index >= 0 && s.charAt(index) == ' ') {
index--;
}
// Step 2: Count the length of the last word
while (index >= 0 && s.charAt(index) != ' ') {
length++;
index--;
}
return length;
}
}