题目
给出一个区间的集合,请合并所有重叠的区间。
示例 1:
输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
分析
一开始拿到这题,本来想用两层循环来做,求两个数组的交集
求交集,数组p[i]和数组p[j]只要满足p[i][1]>=p[j][0]即可
更简便的方法是先给二维数组排序,python里面有直接的sort函数
sort
假如a是一个由元组构成的列表,对该列表进行排序时,我们需要用到参数key,也就是关键词,如下面代码所示,lambda是一个匿名函数,是固定写法;
x表示匿名函数的输入,即列表中的一个元素。在这里,表示一个元组,x只是临时起的一个名字,你可以使用任意的名字;x[0]表示匿名函数的输出,即元组里的第一个元素,即key = x[0];
所以这句命令的意思就是按照列表中第一个元素进行排序。
1 2 3 |
|
答案:
法一:(就是分析里的写法)
这里有知识点:列表的负数索引
-1表示从后往前数第一个值,就是最后一个元素值
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# class intervals:
# def __init__(self):
# self.
class Solution(object):
def merge(self, intervals):
""" :type intervals: List[List[int]]
:rtype: List[List[int]] """
intervals.sort(key = lambda x: x[0])
merged = []
for interval in intervals:
# 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
# def __init__(self,intervals):
# self.intervals = intervals
test = Solution()
merge = test.merge([[0,2],[1,3],[4,6]])
print(merge)
解法二:使用了邻接表
class Solution:
def overlap(self, a, b):
return a.start <= b.end and b.start <= a.end
# generate graph where there is an undirected edge between intervals u
# and v iff u and v overlap.
def build_graph(self, intervals):
graph = collections.defaultdict(list)
for i, interval_i in enumerate(intervals):
for j in range(i+1, len(intervals)):
if self.overlap(interval_i, intervals[j]):
graph[interval_i].append(intervals[j])
graph[intervals[j]].append(interval_i)
return graph
# merges all of the nodes in this connected component into one interval.
def merge_nodes(self, nodes):
min_start = min(node.start for node in nodes)
max_end = max(node.end for node in nodes)
return Interval(min_start, max_end)
# gets the connected components of the interval overlap graph.
def get_components(self, graph, intervals):
visited = set()
comp_number = 0
nodes_in_comp = collections.defaultdict(list)
def mark_component_dfs(start):
stack = [start]
while stack:
node = stack.pop()
if node not in visited:
visited.add(node)
nodes_in_comp[comp_number].append(node)
stack.extend(graph[node])
# mark all nodes in the same connected component with the same integer.
for interval in intervals:
if interval not in visited:
mark_component_dfs(interval)
comp_number += 1
return nodes_in_comp, comp_number
def merge(self, intervals):
graph = self.build_graph(intervals)
nodes_in_comp, number_of_comps = self.get_components(graph, intervals)
# all intervals in each connected component must be merged.
return [self.merge_nodes(nodes_in_comp[comp]) for comp in range(number_of_comps)]
#作者:LeetCode
#链接:https://leetcode-cn.com/problems/merge-intervals/solution/he-bing-qu-#jian-by-leetcode/
#来源:力扣(LeetCode)
#著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
分析:每个字符加入到字符串中,一旦检查到新加入字符和已有的重复,则从重复字符后面一位字符开始,重新循环查找
这也是暴力求解
所以在最后一个非常非常长的用例上超时了
(还有一种解法是,枚举出所有子串,然后放入集合set中,这样)
原解:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import math
def lengthOfLongestSubstring(s: str) -> int:
length = len(s)
#print(length)
substr = ""
max = 0
i=0
index = 0
while(i < length):
#for i in range(0,length-1):
flag = 0
#print(i)
for j in range(index,i):
#如果前面有字符和当前的第i个字符相等,就从重复字符后面继续算
if(s[i] == s[j] ):
flag = 1
# print(i,j)
# #直接修改第一个循环值无效,因为for是迭代器,独立线程工作
i = j
index = j+1
substr = ""
#substr = s[i]
break
if(flag == 0):
substr += s[i]
#print(substr)
if(len(substr) > max):
max = len(substr)
i += 1
return max
str = '''abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\
"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ abcdefghijklmnopqrstuvwxyzABCD" \
"EFGHIJKLMNOPQRSTUVWXYZ0123456789!\"" \
"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ abcdefghijk" \
"lmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\"" \
"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~ abcdefghijklmnopqrstu" \
"vwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!\"#$%&'()*+,-" \
"./:;<=>?@[\\]^_`{|}~ '''
#超时的用例
print(lengthOfLongestSubstring(str))
解析:使用【滑动窗口】思想解题
(我觉得我写的有点摸到这个边了,但是参考代码只用了一层循环,循环值两个变量)
也有用两层循环的呀?看起来好像和我的差不多?为什么AC了emmm
应该是我的变量设置太复杂了?有一个j在range(index,i)中,这是一个单独线程,不如while省事
class Solution:
def lengthOfLongestSubstring(self, s: str) -> int:
if not s:return 0
left = 0
lookup = set()
n = len(s)
max_len = 0
cur_len = 0
for i in range(n):
cur_len += 1
while s[i] in lookup:
lookup.remove(s[left])
left += 1
cur_len -= 1
if cur_len > max_len:max_len = cur_len
lookup.add(s[i])
return max_len
#作者:powcai
#链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-#characters/solution/hua-dong-chuang-kou-by-powcai/
#来源:力扣(LeetCode)
#著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。