python-LeetCode刷题总结

(一)56题合并区间

题目

给出一个区间的集合,请合并所有重叠的区间。

示例 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

= [('b'4), ('a'12), ('d'7), ('h'6), ('j'3)]

a.sort(key=lambda x: x[0])

print(a)
>>>[(
'a'12), ('b'4), ('d'7), ('h'6), ('j'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)
#著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

(二)第3题 无重复字符的最长子串长度

分析:每个字符加入到字符串中,一旦检查到新加入字符和已有的重复,则从重复字符后面一位字符开始,重新循环查找

这也是暴力求解

所以在最后一个非常非常长的用例上超时了

(还有一种解法是,枚举出所有子串,然后放入集合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)
#著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

你可能感兴趣的:(python)