【每日算法】算法复习一

存在重复元素 II

给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums[i]=nums[j],并且 i 和 j 的差的 绝对值 至多为 k。

示例 1:
输入: nums = [1,2,3,1], k = 3
输出: true
示例 2:
输入: nums = [1,0,1,1], k = 1
输出: true
示例 3:
输入: nums = [1,2,3,1,2,3], k = 2
输出: false
def containsNearbyDuplicate(nums, k):
    #定义 一个map,去记录每个元素在数组中的索引
    dic={}
    for i,v in enumerate(nums):
        if v in dic:
            #判断 是否满足索引差的绝对值至多为 k
            # print(dic[v],i,dic[v]-i)
            if i-dic[v]<=k: return true dic[v]="i" false < code></=k:>

存在重复元素 III

&#x7ED9;&#x4F60;&#x4E00;&#x4E2A;&#x6574;&#x6570;&#x6570;&#x7EC4; nums &#x548C;&#x4E24;&#x4E2A;&#x6574;&#x6570;&#xA0;k &#x548C; t &#x3002;&#x8BF7;&#x4F60;&#x5224;&#x65AD;&#x662F;&#x5426;&#x5B58;&#x5728; &#x4E24;&#x4E2A;&#x4E0D;&#x540C;&#x4E0B;&#x6807; i &#x548C; j&#xFF0C;&#x4F7F;&#x5F97;&#xA0;abs(nums[i]-nums[j])<=t ,同时又满足abs(i-j) <="k" 。 如果存在则返回 true,不存在返回 false。 示例 1: 输入:nums="[1,2,3,1]," k="3," t="0" 输出:true 示例 2: 3: 输出:false code></=t>

abs(i-j)=k可知,窗口大小为 k+1时,窗口内的元素索引差都会小于 k,然后在用新增的元素与窗口内的其他元素进行比较差值是否满足 abs(nums[i]-nums[j])<=t< code>&#x5373;&#x53EF;<!--=t<-->

def containsNearbyAlmostDuplicate(nums, k, t):
    #abs(i-j)<=t,可知窗口的大小为k+1 q="collections.deque()" # print(q) for i,v in enumerate(nums): q.append(i) #如果超过窗口的最大值,则移除左左侧的元素 if len(q)>k+1:
            q.popleft()
        for j in q:
            if j</=t,可知窗口的大小为k+1>

可是在提交测试时,显示超时,时间复杂度len(nums)*k,显然滑动窗口的解法不合适,那使用桶排序吧

桶排序的思路:因为差值为 t,所以需要 t+1个桶,则桶内每个元素的差值都 <=t< code>,&#x5982;&#x679C;&#x5F53;&#x524D;&#x6876;&#x5185;&#x6CA1;&#x6709;&#x5143;&#x7D20;&#xFF0C;&#x5219;&#x5F80;&#x524D;&#x4E00;&#x4E2A;&#x6876;&#x67E5;&#x627E;&#xFF0C;&#x5982;&#x679C;&#x6709;&#x503C;&#xFF0C;&#x5E76;&#x4E14;<code><=u-t< code>&#xFF0C;&#x6216;&#x8005;&#x5F80;&#x4E0B;&#x4E00;&#x4E2A;&#x6876;&#x627E;&#xFF0C;&#x5E76;&#x4E14;<code>>=u+t</code>&#x4E3A;&#x6EE1;&#x8DB3;&#x6761;&#x4EF6;&#xFF0C;&#x5E76;&#x4E14;k&#x53BB;&#x7EF4;&#x62A4;&#x6876;&#x7684;&#x603B;&#x4E2A;&#x6570;<!--=u-t<--></code><!--=t<-->

def containsNearbyAlmostDuplicate(nums, k, t):
    def getIdx(u):
        return u//(t+1)
    buckets={}#&#x5B9A;&#x4E49;&#x4E00;&#x4E2A;&#x96C6;&#x5408;
    for i,v in enumerate(nums):
        # print(buckets)
        idx=getIdx(v)#&#x627E;&#x5230;&#x8BE5;&#x5143;&#x7D20;&#x6570;&#x636E;&#x54EA;&#x4E2A;&#x6876;
        #&#x5982;&#x679C;&#x96C6;&#x5408;&#x4E2D;&#x4FDD;&#x5B58;&#x8FD9;&#x4E2A;&#x5143;&#x7D20;,&#x5219;&#x6EE1;&#x8DB3;&#x6761;&#x4EF6;&#x76F4;&#x63A5;&#x8FD4;&#x56DE;
        if idx in buckets:
            return True
        #&#x627E;&#x4E0A;&#x4E00;&#x4E2A;&#xFF0C;&#x4E0B;&#x4E00;&#x4E2A;&#x6876;
        if idx-1 in buckets and buckets[idx-1]>=v-t:
            return True
        if idx+1 in buckets and buckets[idx+1]<=v+t: return true #保存当前元素 buckets[idx]="v" if len(buckets)>k:
            buckets.pop(getIdx(nums[i-k]))
    return False
</=v+t:>

长度最小的子数组

&#x7ED9;&#x5B9A;&#x4E00;&#x4E2A;&#x542B;&#x6709;&#xA0;n&#xA0;&#x4E2A;&#x6B63;&#x6574;&#x6570;&#x7684;&#x6570;&#x7EC4;&#x548C;&#x4E00;&#x4E2A;&#x6B63;&#x6574;&#x6570; target &#x3002;
&#x627E;&#x51FA;&#x8BE5;&#x6570;&#x7EC4;&#x4E2D;&#x6EE1;&#x8DB3;&#x5176;&#x548C; &#x2265; target &#x7684;&#x957F;&#x5EA6;&#x6700;&#x5C0F;&#x7684; &#x8FDE;&#x7EED;&#x5B50;&#x6570;&#x7EC4;&#xA0;[numsl, numsl+1, ..., numsr-1, numsr] &#xFF0C;&#x5E76;&#x8FD4;&#x56DE;&#x5176;&#x957F;&#x5EA6;&#x3002;&#x5982;&#x679C;&#x4E0D;&#x5B58;&#x5728;&#x7B26;&#x5408;&#x6761;&#x4EF6;&#x7684;&#x5B50;&#x6570;&#x7EC4;&#xFF0C;&#x8FD4;&#x56DE; 0 &#x3002;
&#x8F93;&#x5165;&#xFF1A;target = 7, nums = [2,3,1,2,4,3]
&#x8F93;&#x51FA;&#xFF1A;2
&#x89E3;&#x91CA;&#xFF1A;&#x5B50;&#x6570;&#x7EC4; [4,3] &#x662F;&#x8BE5;&#x6761;&#x4EF6;&#x4E0B;&#x7684;&#x957F;&#x5EA6;&#x6700;&#x5C0F;&#x7684;&#x5B50;&#x6570;&#x7EC4;&#x3002;
&#x8F93;&#x5165;&#xFF1A;target = 4, nums = [1,4,4]
&#x8F93;&#x51FA;&#xFF1A;1

使用可变的窗口,首先扩大窗口,使窗口内的总和扩大,当出现和>=target时,记录窗口左右边界的值,然后再缩小窗口,直到小于target时,在记录左右边界,并与之前比较,记录最小的那个;然后在重复上面的步骤,直到数组结尾。

def minSubArrayLen(target, nums):
    #&#x5206;&#x522B;&#x8BB0;&#x5F55;&#x5DE6;&#x53F3;&#x8FB9;&#x754C;&#xFF0C;&#x548C;&#x7A97;&#x53E3;&#x5185;&#x548C;
    left,right,total=0,0,0
    res=(left,float('inf'))
    n=len(nums)
    while right<n: total+="nums[right]" if total>=target:#&#x603B;&#x548C;&#x5927;&#x4E8E;&#x7B49;&#x4E8E;target&#x65F6;
            #&#x5DE6;&#x79FB;&#x5DE6;&#x8FB9;&#x754C;
            while left<=right and total>=target:
                #&#x8BB0;&#x5F55;&#x5DE6;&#x53F3;&#x8FB9;&#x754C;
                if res[1]-res[0]>right-left:
                    res=(left,right)
                total-=nums[left]
                left+=1
        right+=1
    return 0 if res[1]>n else res[1]-res[0]+1
</=right></n:>

无重复字符的最长子串

&#x7ED9;&#x5B9A;&#x4E00;&#x4E2A;&#x5B57;&#x7B26;&#x4E32; s &#xFF0C;&#x8BF7;&#x4F60;&#x627E;&#x51FA;&#x5176;&#x4E2D;&#x4E0D;&#x542B;&#x6709;&#x91CD;&#x590D;&#x5B57;&#x7B26;&#x7684;&#xA0;&#x6700;&#x957F;&#x5B50;&#x4E32;&#xA0;&#x7684;&#x957F;&#x5EA6;&#x3002;
&#x793A;&#x4F8B;&#xA0;1:
&#x8F93;&#x5165;: s = "abcabcbb"
&#x8F93;&#x51FA;: 3
&#x89E3;&#x91CA;: &#x56E0;&#x4E3A;&#x65E0;&#x91CD;&#x590D;&#x5B57;&#x7B26;&#x7684;&#x6700;&#x957F;&#x5B50;&#x4E32;&#x662F; "abc"&#xFF0C;&#x6240;&#x4EE5;&#x5176;&#x957F;&#x5EA6;&#x4E3A; 3&#x3002;
&#x793A;&#x4F8B; 2:
&#x8F93;&#x5165;: s = "bbbbb"
&#x8F93;&#x51FA;: 1
&#x89E3;&#x91CA;: &#x56E0;&#x4E3A;&#x65E0;&#x91CD;&#x590D;&#x5B57;&#x7B26;&#x7684;&#x6700;&#x957F;&#x5B50;&#x4E32;&#x662F; "b"&#xFF0C;&#x6240;&#x4EE5;&#x5176;&#x957F;&#x5EA6;&#x4E3A; 1&#x3002;
&#x793A;&#x4F8B; 3:
&#x8F93;&#x5165;: s = "pwwkew"
&#x8F93;&#x51FA;: 3
&#x89E3;&#x91CA;: &#x56E0;&#x4E3A;&#x65E0;&#x91CD;&#x590D;&#x5B57;&#x7B26;&#x7684;&#x6700;&#x957F;&#x5B50;&#x4E32;&#x662F;&#xA0;"wke"&#xFF0C;&#x6240;&#x4EE5;&#x5176;&#x957F;&#x5EA6;&#x4E3A; 3&#x3002;
&#xA0;    &#x8BF7;&#x6CE8;&#x610F;&#xFF0C;&#x4F60;&#x7684;&#x7B54;&#x6848;&#x5FC5;&#x987B;&#x662F; &#x5B50;&#x4E32; &#x7684;&#x957F;&#x5EA6;&#xFF0C;"pwke"&#xA0;&#x662F;&#x4E00;&#x4E2A;&#x5B50;&#x5E8F;&#x5217;&#xFF0C;&#x4E0D;&#x662F;&#x5B50;&#x4E32;&#x3002;
&#x793A;&#x4F8B; 4:
&#x8F93;&#x5165;: s = ""
&#x8F93;&#x51FA;: 0

依然使用双指针的方式定义窗口的左右边界,使用hash来保存窗口内的元素,当新元素在hash里面的话,移动左边界并逐步删除hash里面的元素,直到不存在重复的元素位置,并计算dic的长度

import collections
def lengthOfLongestSubstring(s):
    dic={}#&#x4FDD;&#x5B58;&#x7A97;&#x53E3;&#x5185;&#x7684;&#x5143;&#x7D20;
    left=0#&#x5DE6;&#x53F3;&#x79FB;&#x52A8;&#x7684;&#x7A97;&#x53E3;
    n=len(s)
    res=0#&#x6700;&#x540E;&#x7684;&#x7ED3;&#x679C;
    q=collections.deque()
    for right in range(n):
        c=s[right]
        #&#x5982;&#x679C;&#x5728;&#x7A97;&#x53E3;&#x91CC;&#x9762;&#xFF0C;&#x4ECE;&#x5DE6;&#x5230;&#x53F3;&#x9010;&#x4E2A;&#x5224;&#x65AD;&#x662F;&#x5426;&#x76F8;&#x7B49;&#xFF0C;&#x76F8;&#x7B49;&#x5219;&#x5220;&#x9664;
        while c in dic and left<right: dic.pop(s[left]) left+="1" dic[c]="right" res="max(res,len(dic))" return < code></right:>

滑动窗口最大值

`
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
返回滑动窗口中的最大值。
示例 1:
输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置 最大值

Original: https://www.cnblogs.com/hitechr/p/15120088.html
Author: Hitechr
Title: 【每日算法】算法复习一

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/590441/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • fastposter v2.8.1 发布 电商海报生成器

    fastposter v2.8.1 发布 电商海报生成器 fastposter海报生成器,电商海报编辑器,电商海报设计器,fast快速生成海报 海报制作 海报开发。二维码海报,图片…

    Java 2023年6月5日
    070
  • 20220728-在IDEA中进行Java的断点调试Debug

    断点调试介绍 断点调试是指在程序的某一行设置一个断点,在调试时,程序运行到这一行就会停住,然后你可以一步一步往下调试,调试过程中可以看各个变量当前的值,出错的话,调试到出错的代码行…

    Java 2023年6月15日
    089
  • java编译问题之Description Resource Path Location Type Java compiler level does not match the version of

    project 编译问题,需要三处的jdk版本要保持一致,才能编译通过。 1、在项目上右键properties->project Facets->修改右侧的versio…

    Java 2023年6月5日
    0117
  • Java 多维数组

    二维数组 数组不止能存储某具体值,还能用 数组 储存数组。 介绍: 我们前面学的数组都是一维数组,数组里存储的是具体的值,就是一位数组。 数组不仅可以储存值,还能储存另外一个完整的…

    Java 2023年6月5日
    070
  • IDEA 启动报错 java.nio.charset.MalformedInputException: Input length=2

    idea 启动提示 other.xml 无法解析 …… cannot parse file other.xml: java.nio.charset.Malf…

    Java 2023年5月29日
    059
  • 解决List遍历删除元素提示ConcurrentModificationException

    解决List遍历删除元素提示ConcurrentModificationException JDK1.8提供新的API ===> removeIf @Test public …

    Java 2023年6月5日
    078
  • SpringBoot整合SpringSecurityOauth2实现鉴权-动态权限

    写在前面 思考:为什么需要鉴权呢? 系统开发好上线后,API接口会暴露在互联网上会存在一定的安全风险,例如:爬虫、恶意访问等。因此,我们需要对非开放API接口进行用户鉴权,鉴权通过…

    Java 2023年6月16日
    093
  • springboot对LocalDateTime类型入参和接口返回值格式化

    背景 使用过java8的朋友应该都知道LocalDateTime类型,它作为全新的日期和时间API ,对比Date类型有着很大的优势,极大的方便了我们对于时间和日期的操作。不过,如…

    Java 2023年5月30日
    072
  • Java正则表达式

    1、为了解决上述问题。Java提供了正则表达式技术,专门来处理类似于文本问题 2、简单来说:正则表达式是对字符串进行模式匹配的技术 3、正则表达式:regular expressi…

    Java 2023年5月29日
    060
  • 【JDK】分析 String str=““ 与 new String()

    一、基础概念 为了讲清楚他们的差异,这里先介绍几个概念。 1.1 常量池 所谓常量池:顾名思义就是用来存放一些常量的。该常量是在 编译期被确定,并被保存在已编译的 .class文件…

    Java 2023年6月5日
    091
  • 公众号资料分享

    在公众号分享两份资料一份是面试资料整理,面试资料针对Java方向,从JVM虚拟机到机器学习,云计算都有涉及,虽然机器学习有些内容比较简单,但是整体的知识框架还是列出来了,总结的非常…

    Java 2023年5月30日
    057
  • CAS 单点登录【2】自定义用户验证

    方案1:CAS默认的JDBC扩展方案: CAS自带了两种简单的通过JDBC方式验证用户的处理器。 这两个处理类位于cas-server-support-jdbc这个扩展工程下。 第…

    Java 2023年5月29日
    066
  • Linux(RedHat、Ubuntu)安装docker

    Linux(RedHat、Ubuntu)安装docker 前言 docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的…

    Java 2023年6月15日
    052
  • 动手制作 java版本切换 多版本JDK安装 windows JDK版本 切换

    1、下载各版本安装包,指定安装位置顺序安装 2、删除注册表,文件和环境变量 文件: C:\Windows\System32 下java相关文件如 java.exe javaw.ex…

    Java 2023年5月29日
    051
  • 通往架构师之路的三本书,高分!

    之前我写过几篇架构师、架构设计相关的文章。说实话,想通过几篇文章就把架构师的方方面面说明白,挺难的。 这可能需要一系列的文章,今天就给大家安排了这篇文章。 很多程序员都有和下面类似…

    Java 2023年6月7日
    072
  • dubbo源码分析1(搭建环境)

    好久没有写博客了, 一方面是最近工作太忙了,还有就是因为在研究dubbo源码相关的,感觉没有怎么研究懂,我擦(╯—﹏—)╯(┷━━━┷ 由于以前是使用springboot开发的,很…

    Java 2023年6月6日
    0103
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球