Top 100 Linked Question 修炼------第32题、第33题

32. Longest Valid Parentheses

题目链接

题目解释:给定一个只包含左括号和右括号的字符串,要求你求出最长的有效括号匹配对。

例如:

Input: ")()())"
Output: 4

那么这个output  4就是两个括号对(即4)所得到的。好的,题目就是这样的,那么主要是分析一下解题思路:

题目思路:假设你是具备一定的专业的知识的,学过算法与数据结构,那么一定记得在栈的应用里面,有个特别重要的应用,那就是括号匹配,它的内容也是给定一个字符串,其中包含大括号、中括号、小括号,让你写程序判断给的字符串是不是有效的,即用通俗的话来讲就是每个'('都会有一个恰当的位置上存在与之匹配的')',这样就是称之为括号匹配,那么同理,我们可以借鉴这样的算法思想,将它运用到本题中:

  在本题中,我们将每一个字符都与特点的标号对应,本题存在小小的变动就是不是将特点的字符压栈,而是将标号压栈,这样就可以在每次计算的时候直接计算当前的最大距离,具体的注释可以尝试见代码:

class Solution:
    def longestValidParentheses(self, s: str) -> int:
        max_len=0
        stack=[]
        # 为了保证到目前为止是否是有效的
        stack.append(-1)
        for i,value in enumerate(s):
            if value=='(':
                stack.append(i)
            else:
                stack.pop()
                if len(stack)==0:
                    stack.append(i)
                else:
                    max_len=max(max_len,i-stack[-1])
        return max_len

具体的也可以看一下题目给的动画解答,真是太完美了

33. Search in Rotated Sorted Array

题目解释

题目解释:给定一个已经排好序的数组,将它按照某个结点进行旋转(如[0,1,2,4,5,6,7] 将会进行旋转 [4,5,6,7,0,1,2]),然后在这个数组中寻找某个值,若找到则返回该结点的位置,若找不到位置则返回-1

要求:要求你写的算法的时间复杂度为O(lgn)

算法思想:当博主一看到这个要求的算法时间复杂度的时候,一定是采用二分法,因为这个算法的时间复杂度太过特殊了,直接就是O(lgn),与二分法相对应。那么确实如此,笔者也按照二分法的思路来解答本题:我们再次来观看本题,发现这个经过"旋转"之后的数组是有些奇特的,它是部分有序的如后面的[0,1,2]三个元素有序,前面的元素有序,那么我们可以按照这个特点,借助于二分法的思想,设置三个指针,分析如下:

list为a,low,mid以及high,其中mid=(low+high)//2
当我们需要找寻的数据(target)>a[mid],那么可以更新low或者high的值

这样一看,似乎与传统的二分法没有区别,其实,当然是有区别的,我们的二分法只适用于有序数组,而经过旋转之后的数组只是部分有序的,并不适合于传统的二分法,那么需要改进的地方在哪里呢?

关键就是在mid这个点处于哪个升序的序列中,然后进行相关的操作,代码中有详细的注释,可以查看一下结果:

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        start,end = 0,len(nums) - 1
        while start <= end:
            mid = (start + end)//2
            if nums[mid] == target:
                return mid
            if nums[mid] >= nums[start]:  # 当nums[mid]属于左边升序序列时
                # target的值在start~mid之间
                if target >= nums[start] and target < nums[mid]:
                    end = mid - 1
                else:
                    start = mid + 1
            if nums[mid] < nums[end]:  # 当nums[mid]属于右边升序序列时
                if target > nums[mid] and target <= nums[end]:
                    start = mid + 1
                else:
                    end = mid - 1
        return -1

总结

这两个题应该来说找到确定的方法之后是不困难的,孰能生巧,嗯,对,就是这样....

想起朋友的一句话,很有道理:

生活不止眼前的苟且,还有远方的苟且,smile alive.

猜你喜欢

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