Top 100 Linked Question 修炼------第三题、第四题

3.Longest Substring Without Repeating Characters

题目大意:给出一个字符串,需要你判断最长的无重复子串的长度

题目链接

题目分析:首先是明确子串的含义,以题目的内容举例:“

pwwkew

对于这个单词,子串它是自带连续的定义的,即wwk 是这个字符串的一个子串,而wwe不是它的一个子串,具体的内容类推...

那么拿到这个题目是怎么思考的呢?最简单的思考方式:设置一个list,然后将list里面的字符求得都是不同的,最后求得这个字典里面最长的字符串长度即可:

还是以这个字符串为例,讲解思考的过程(定义a=[]):

1.对于p,此时列表里面没有数据,直接将p加入到list中;

2.对于w,同样将w加入到list中,此时list为a=['p','pw']

3.对于第二个w,接下来就是操作的关键了:因为list里面存在w,那么我们先找到这个w的位置,此时对应的位置的下标为:1,是处在最后一个位置,那么可以将list更新为:a[i-1][pos+1:]+s[i]   (即是取上个list中的元素,然后将pos后面的元素取出来,新的list上再加上这个重复的元素s[i]),即更新后的list为:['p','pw','w']

4.将k加入:['p','pw','w',‘wk’]

5.将e加入:['p','pw','w',‘wk’,'wke']

6.此时现在的字符串为‘w’,同3,自己自己理解一个那个表达式,这里只给出操作之后的结果:['p','pw','w',‘wk’,'wke',‘kew’]

7.获取list中最长的字符长度

注意:有个小技巧就是对于新想要进入的字符,比较的过程是仅仅相对于上一个list中的元素的...

有了上面的铺垫,可以给出代码了,基本上就是上面过程的模拟:

    def lengthOfLongestSubstring(self, s: str) -> int:
        if len(s)<2:
            return len(s)
        maxi=[s[0]]
        for i in range(1,len(s)):
            if s[i] in maxi[i-1]:
                pos=maxi[i-1].find(s[i])
                maxi.append(maxi[i-1][pos+1:]+s[i])
            else:
                maxi.append(maxi[i-1]+s[i])
        return len(max(maxi, key=len))

4.Median of Two Sorted Arrays

题目大意:给出两个已经排好序的数组,如果将这两个合并成一个有序数组(本人的理解,题目不是要求合并),求这个新数组的中位数,要求时间复杂度O(log(m+n))

题目链接

题目分析:在leetcode解题方案中,蛮多大牛都是直接将两个数组直接进行合并,然后再求取中位数,但是本小白确实跑了一份这样的代码,确实也是很简单,下面仅仅给出这份代码,然后说出我的疑虑:

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        if len(nums1)>len(nums2):
            nums1, nums2 = nums2, nums1
        if not nums1:
            return self.find_medium(nums2)
        else:
            num=nums1+nums2
            nums=sorted(num)
            return self.find_medium(nums)
    def find_medium(self,num):
        length = len(num)
        if length % 2 == 1:
            return num[length // 2]
        else:
            return (num[length // 2 - 1] + num[length // 2]) / 2.0

本小白的疑问:这样直接操作的方式怎么能确定时间复杂度呢?这个总体的时间消耗主要是在sorted()方法上,但是你怎么知道这个sorted方法是怎么操作的呢?内部采用的最优的算法是什么呢?所以呀,我觉得我还是比较能接受下面的分析方式(虽然以后在笔试的时候可能会采用上面的解答方法...(python简单呐,嘿嘿)):

既然我们需要找到是两个序列的中位数,为何不直接就是采用两个序列的方式去寻找呢?可以采用的分析思路如下:、

令两个list的标记分别为nums1,nums2:

取得nums1、nums2的中位数,分别记作a,b

1.若a=b,则a或者b即为所求的中位数,算法结束;

2.如a<b,则舍弃序列nums1中较小的一般,同时舍弃序列nums2中较大的一半,要求同时舍弃的长度相等

3.如a>b,则舍弃序列nums1中较大的一般,同时舍弃序列nums2中较小的一半,要求同时舍弃的长度相等

重复步骤1,2,3,直到两个序列中均只含一个元素为止,较小者即为所求的中位数

def findMedianSortedArrays(self, A, B):
    l = len(A) + len(B)
    if l % 2 == 1:
        return self.kth(A, B, l // 2)
    else:
        return (self.kth(A, B, l // 2) + self.kth(A, B, l // 2 - 1)) / 2.   
    
def kth(self, a, b, k):
    if not a:
        return b[k]
    if not b:
        return a[k]
    ia, ib = len(a) // 2 , len(b) // 2
    ma, mb = a[ia], b[ib]
    
    if ia + ib < k:
        if ma > mb:
            return self.kth(a, b[ib + 1:], k - ib - 1)
        else:
            return self.kth(a[ia + 1:], b, k - ia - 1)
    else:
        if ma > mb:
            return self.kth(a[:ia], b, k)
        else:
            return self.kth(a, b[:ib], k)

总结

又被虐了,得到了思路,学到了代码,很开心...

猜你喜欢

转载自blog.csdn.net/sir_TI/article/details/88379828