首页 > 编程语言 >献芹奏曝-Python面试题-算法-滑动窗口篇

献芹奏曝-Python面试题-算法-滑动窗口篇

时间:2022-12-13 17:15:27浏览次数:79  
标签:面试题 cur nums Python max heapq 献芹 range result

上一篇:献芹奏曝-Python面试题 

      开篇的话:本文目的是收集和归纳力扣上的算法题,希望用python语言,竭我所能做到思路最清奇、代码最简洁、方法最广泛、性能最高效,了解常见题目,找到最利于记忆的答案,更加从容的应对面试。希望广思集益,共同进步。

一、滑动窗口篇

  1. 3. 无重复字符的最长子串(难度系数✯) 

    class Solution:
        def lengthOfLongestSubstring(self, s: str) -> int:
            cur_len = 0 # 定义当前长度
            start_ind = 0 # 滑块的起始位置
            end_ind = 0 # 滑块的终止位置
            dict_item = {} 
            if not s:
                return 0
            for index, item in enumerate(s):
                end_ind = index # 尾部滑块动起来
                if item in s[start_ind:end_ind]:
                   cur_len = max(cur_len,end_ind-start_ind)  
                   start_ind = dict_item.get(item)+1 # 如果存在,头部滑块动起来
                dict_item[item] = index # 字段的值判断后更新
                    
            return max(cur_len,end_ind-start_ind+1)
    
     
    View Code

    运行结果:1:耗时超过48%。2:内存超过74% 

    知识点/技巧:1:双指针、滑动窗口。2:注意返回时再重新算一下

  2. 239. 滑动窗口最大值(难度系数✯✯✯) 

    class Solution:
        def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
            head = 0 # 定义首
            tail = k-1 # 定义尾
            cur_max = max(nums[0:k])
            result_list = [cur_max]
            n = len(nums) # 定义长度
    
            for index in range(k,n):             
                if nums[head]==cur_max:
                    # 如果当前最大值即将被滑出,重新选举一个
                    cur_max=max(nums[index-k+1:index+1])
                if nums[index] > cur_max:
                    # 取而代之
                    cur_max = nums[index]
                result_list.append(cur_max)
                head += 1
                tail += 1
            return result_list
    超时的方法

    知识点/技巧:1:按照双指针滑动,直接硬搞

    class Solution:
        """
        痛定思痛,之所以超时是由于  cur_max=max(nums[index-k+1:index+1]) 方法性能太差
        定义一个 单调递减的序列,里面存储的是索引id
        """
    
        def get_new_que_list(self, que_list, nums, index, k):
            if nums[que_list[0]] <= nums[index]:
                # 如果最大值 <= 当前值,清空队列
                que_list = []
                que_list.append(index)
                return que_list
            # 确保队列有序的关键所在
            while que_list and nums[que_list[-1]] <= nums[index]:
                # 把队尾的元素与当前值比较,如果小就删除;
                que_list.pop()
            while que_list and que_list[0] <= index - k:
                # 头部元素已经滑出
                que_list.pop(0)
            que_list.append(index)
            return que_list
    
        def maxSlidingWindow(self, nums, k):
            n = len(nums)  # 定义长度
            result_list = [nums[0]]
            que_list = [0]
    
            for i in range(k):
                que_list = self.get_new_que_list(que_list, nums, i, k)
                if result_list[0] <= nums[i]:
                    result_list[0] = nums[i]
    
            for i in range(k, n):
                que_list = self.get_new_que_list(que_list, nums, i, k)
                result_list.append(nums[que_list[0]])
            return result_list
    单调队列--(通过list模拟)

    运行结果:1:耗时超过23%。2:内存超过80% 

    知识点/技巧:1:维护单调队列的队首元素和队尾元素

    class Solution:
        """
        使用collections中的队列,
        """
        def maxSlidingWindow(self, nums, k):
            n = len(nums)  # 定义长度
            ans = []
            q = collections.deque() # ps:引用collections 中的队列
    
            for i in range(k):
                # 初始化 队列 (更新队尾元素)
                while q and nums[q[-1]]<=nums[i]:
                    q.pop()
                q.append(i)
            ans.append(nums[q[0]])            
    
            for i in range(k,n):
                # 队列 (更新队尾元素)
                while q and nums[q[-1]]<=nums[i]:
                    q.pop()
                # 队列 (更新队首元素)
                while q and q[0]<=i-k:
                    q.popleft()  # 注意队列删除左元素使用的是popleft()
                q.append(i)
                ans.append(nums[q[0]])  
            return ans
    单调队列--(使用collections的deque)比使用list性能更好

    运行结果:1:耗时超过95%。2:内存超过48% 

    知识点/技巧:1:维护单调队列的队首元素和队尾元素.2:注意引用的是collections中的deque()。它删除队首元素使用的popleft()

    class Solution:
        """
        引用heapq使用堆搞定
        # 注意 堆的调用都以heapq.heapXX开头,
            初始化<=>heapq.heapify(h); # 没有返回值
            添加元素<=>heapq.heappush();
            删除顶元素<=>heapq.heappop();
    
        """
        def maxSlidingWindow(self, nums, k):
            n = len(nums)  # 定义长度
            ans = []    
            # 由于python中的是“小根堆(最小的值在根节点)” 
            h = [(-nums[i],i) for i in range(k)]
    
            # 初始化堆:heapq.heapqify(array)
            heapq.heapify(h)
            ans.append(-h[0][0])            
    
            for i in range(k,n):
                while h and h[0][1]<=i-k:
                    # 适时弹出
                    heapq.heappop(h)
                heapq.heappush(h,(-nums[i],i)) # 追加元素
                ans.append(-h[0][0])  
            return ans
    优先队列--使用堆处理

    运行结果:1:耗时超过49%。2:内存超过14% 

    知识点/技巧:1:引用heapq使用堆.2:堆的调用都以heapq.heapXX开头。 初始化<=>heapq.heapify(h); # 没有返回值        添加元素<=>heapq.heappush();        删除顶元素<=>heapq.heappop();

  3. 611. 有效三角形的个数(难度系数✯✯) 

    class Solution:
        def triangleNumber(self, nums: List[int]) -> int:
            # 排序 +  双指针滑动 (i为第1个指针,j 和k 分别为第2和第3个指针)
            nums.sort() # 排序
            n = len(nums)
            result = 0
            for i in range(n):
                for j in range(i+1,n):
                    k = j+1
                    while k<n and nums[i]+nums[j]>nums[k]:
                        result += 1
                        k += 1
            return result
    超时的方法

    知识点/技巧:k的值每次从j+1开始不妥,可以优化。可以想象成游戏没有存档,每次失败后都从j+1处重新打。其实是可以适当存档的。

    class Solution:
        def triangleNumber(self, nums: List[int]) -> int:
            # 排序 +  双指针滑动 
            nums.sort() # 排序
            n = len(nums)
            result = 0
            for i in range(n-2):
                k = i # 存档
                for j in range(i+1,n-1):
                    while k+1<n and nums[i]+nums[j]>nums[k+1]:
                        k += 1 
                    result += max(k-j,0)
            return result
    排序+指针存档

    运行结果:1:耗时超过54%。2:内存超过88% 

    知识点/技巧:1:先排序,2:对k存档,少去了很多不必要的重复计算

    class Solution:
        def triangleNumber(self, nums) -> int:
            # 排序 +  双指针滑动 (i为第1个指针,j 和k 分别为第2和第3个指针)
            nums.sort()  # 排序
            n = len(nums)
            result = 0
            for i in range(n - 2):
                for j in range(i + 1, n - 1):
                    left = j
                    right = n - 1
                    k = j
                    while left <= right:
                        mid = (right + left) // 2
                        if nums[mid] < nums[i] + nums[j]:
                            k = mid
                            left = mid + 1
                        else:
                            right = mid - 1
                    result += max(k - j, 0)
            return result
    排序+二分查找

    运行结果:1:耗时超过5%。2:内存超过94% 

    知识点/技巧:1:先排序,2:再进行二分查找

    class Solution:
        def triangleNumber(self, nums) -> int:
            # 排序 +  二分查找
            nums.sort()  # 排序
            n = len(nums)
            result = 0
            for i in range(n - 2):
                for j in range(i + 1, n - 1):
                    k = bisect.bisect_left(nums, nums[i] + nums[j]) - 1
                    result += max(k - j, 0)
            return result
    利用python提供的二分查找

    运行结果:1:耗时超过34%。2:内存超过91% 

    知识点/技巧:1:先排序,2:利用python内部的二分查找

标签:面试题,cur,nums,Python,max,heapq,献芹,range,result
From: https://www.cnblogs.com/YK2012/p/16938610.html

相关文章

  • 献芹奏曝-Python面试题-算法-数学篇
    上一篇:献芹奏曝-Python面试题    开篇的话:本文目的是收集和归纳力扣上的算法题,希望用python语言,竭我所能做到思路最清奇、代码最简洁、方法最广泛、性能最高效,了解......
  • 献芹奏曝-Python面试题-算法-背包问题
    上一篇:献芹奏曝-Python面试题    开篇的话:本文目的是收集和归纳力扣上的算法题,希望用python语言,竭我所能做到思路最清奇、代码最简洁、方法最广泛、性能最高效,了解......
  • Python之退出函数
    有时候需要写的pythonexe有返回值,今天就看了下,发现了一个函数sys.exit(),用起来还可以,但是有个问题。如果你需要用十六进制的数退出的话,不要超过0x7fffffff。因为sys.exit(......
  • python下的符号函数
    一、符号函数的入门:1、符号函数使用准备,导库from sympy import*2、定义符号x,y,z=symbols('xyz')3、应用符号e=cos(x)+14、画符号函数的......
  • Python字符串格式化的三种方式
     #方式一:%name='张三'age=20score=22.556print('%s的年龄为:%d,成绩%f'%(name,age,score))#%3s为此处占3个字符位,不够3位前面空位#%04d为此处占4个......
  • python及pycharm虚拟环境配置
    python虚拟环境"""在实际项目开发中,我么只会给项目配备其所需的环境,所以就需要虚拟环境"""#1.什么是虚拟环境?能够针对相同版本的解释器创建多个分身,每个分身可......
  • win102-Windows环境下pycharnpython安装版下载、配置(win10-x64位32g内存)
    win102-Windows环境下pycharnpython安装版下载、配置(win10-x64位32g内存)1、建议首先安装anaconda(注意配置path环境)。  python国内镜像地址:http://npm.taobao.org/mirr......
  • python基础
    python基础1.0:python的起源1991年,第一个python解释器诞生,他是用C语言实现的,并能够调用c语言的库文件1.1:解释器​计算机不能直接理解任何除机器语言外的语言,所以必须要......
  • Selenium4+Python3系列(十三) - 与docker中的jenkins持续集成
    前言文章更新到这一篇时,其实我还是很开心的,因为这也正是这系列教程的最后一篇文章,也算是完成了一个阶段性的小目标,也很感谢那些愿意看我文章与我交流学习的同学,感谢有你们......
  • python在pycharm写好程序后,简单的部署方法-非生产环境
    这里说的简单,是真正的简单,不是那种长篇大论方法一:打开cmd,或者用pycharm打开终端,安装pyinstaller详见,http://c.biancheng.net/view/2690.html这种方法可以生成独立的exe......