15天算法入门(六)

简介: 本文主要讲无重复字符的最长子串和字符串的排列

网络异常,图片无法展示
|


网络异常,图片无法展示
|


无重复字符的最长子串


题目


给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

 

示例 1:
输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
复制代码


题解


该题考察了字符串的一些用法(字符串截取、查找)。在遍历过程中,通过当前字符与前面无重复子字符串比较:


  • 当前字符存在子串中,将子串左边界收缩到重复的下一位值;
  • 不重复,则右边界继续扩大。


关于最大值,比较子串出现的最大长度。

例子:

s = "abcabcbb"

当开始时,子串的左右边界应该指向起始位置。当前截取的子串str应该为空。

网络异常,图片无法展示
|
子串str中不包含当前a字符,所以,扩大子串右边界,继续向下遍历。

当循环到第二个a时,情况如下:

网络异常,图片无法展示
|

此时截取的子串中包含了当前的字符,进行查找子串中出现重复的位置,将缩小左边界至重复位置的下一位。继续循环,取最大值。

网络异常,图片无法展示
|

当再次出现重复时:

网络异常,图片无法展示
|
依旧缩小左边界。在此,p1并不是简单的移动到子串重复位置的下一位。当前子串重复位置为0,下一位即1。但是如果移动到1的话,左边界就并未缩小。所以移动的时候,还需要加上左边界原始的位置。此时p1移动到2位置。 以此类推,在每次遍历中,取子串长度的最大数。最后遍历完成后,返回最大值即可。


代码


var lengthOfLongestSubstring = function (s) {
    let p1 = 0, index = 0, max = 0
    while (index <= s.length) {
        let str = s.slice(p1, index)
        let isExitIndex = str.indexOf(s[index])
        if (isExitIndex > -1) p1 += isExitIndex + 1
        max = Math.max(max, str.length)
        index++
    }
    return max
};


字符串的排列


题目


给你两个字符串 s1s2 ,写一个函数来判断 s2 是否包含 s1 ****的排列。

换句话说,s1 的排列之一是 s2子串

示例 1:
输入: s1 = "ab" s2 = "eidbaooo"
输出: true
解释: s2 包含 s1 的排列之一 ("ba").


题解


该题主要考察通过子串全排列能否联想到使用字符数组解决。说实话一开始我是没想到。。。


使用两个长度为26的数组,分别记录两个字符串每个字符出现的次数。用一个长度为26的数组记录s1中出现的次数。在遍历s2时,通过使用两个左右指针截取s2可能的子串。在用一个长度为26的数组记录截取的子串字符数。当s1的数组等于截取子串数组时就满足条件。


代码


var checkInclusion = function (s1, s2) {
    let arr1 = new Array(26).fill(0)
    let arr2 = new Array(26).fill(0)
    for (let i = 0; i < s1.length; i++) {
        arr1[s1[i].charCodeAt() - 'a'.charCodeAt()]++
    }
    let i = 0, j = 0
    while (i < s2.length) {
        arr2[s2[i].charCodeAt() - 'a'.charCodeAt()]++
        while (j <= i && arr2[s2[j].charCodeAt() - 'a'.charCodeAt()] > arr1[s2[j].charCodeAt() - 'a'.charCodeAt()]) {
            arr2[s2[j].charCodeAt() - 'a'.charCodeAt()]--
            j++
        }
        i++
        if (arr1.join('') === arr2.join('')) return true
    }
    return false
};


题目来源:leetcode

目录
相关文章
|
25天前
|
存储 算法
算法入门:专题二---滑动窗口(长度最小的子数组)类型题目攻克!
给定一个正整数数组和目标值target,找出总和大于等于target的最短连续子数组长度。利用滑动窗口(双指针)优化,维护窗口内元素和,通过单调性避免重复枚举,时间复杂度O(n)。当窗口和满足条件时收缩左边界,更新最小长度,最终返回结果。
|
1月前
|
存储 算法
算法入门:专题一:双指针(有效三角形的个数)
给定一个数组,找出能组成三角形的三元组个数。利用“两边之和大于第三边”的性质,先排序,再用双指针优化。固定最大边,左右指针从区间两端向内移动,若两短边之和大于最长边,则中间所有组合均有效,时间复杂度由暴力的O(n³)降至O(n²)。
|
1月前
|
存储 算法 编译器
算法入门:剑指offer改编题目:查找总价格为目标值的两个商品
给定递增数组和目标值target,找出两数之和等于target的两个数字。利用双指针法,left从头、right从尾向中间逼近,根据和与target的大小关系调整指针,时间复杂度O(n),空间复杂度O(1)。找不到时返回{-1,-1}。
|
4月前
|
机器学习/深度学习 数据采集 算法
你天天听“数据挖掘”,可它到底在“挖”啥?——数据挖掘算法入门扫盲篇
你天天听“数据挖掘”,可它到底在“挖”啥?——数据挖掘算法入门扫盲篇
88 0
|
机器学习/深度学习 人工智能 算法
深度学习入门:理解神经网络与反向传播算法
【9月更文挑战第20天】本文将深入浅出地介绍深度学习中的基石—神经网络,以及背后的魔法—反向传播算法。我们将通过直观的例子和简单的数学公式,带你领略这一技术的魅力。无论你是编程新手,还是有一定基础的开发者,这篇文章都将为你打开深度学习的大门,让你对神经网络的工作原理有一个清晰的认识。
|
8月前
|
机器学习/深度学习 算法 机器人
强化学习:时间差分(TD)(SARSA算法和Q-Learning算法)(看不懂算我输专栏)——手把手教你入门强化学习(六)
本文介绍了时间差分法(TD)中的两种经典算法:SARSA和Q-Learning。二者均为无模型强化学习方法,通过与环境交互估算动作价值函数。SARSA是On-Policy算法,采用ε-greedy策略进行动作选择和评估;而Q-Learning为Off-Policy算法,评估时选取下一状态中估值最大的动作。相比动态规划和蒙特卡洛方法,TD算法结合了自举更新与样本更新的优势,实现边行动边学习。文章通过生动的例子解释了两者的差异,并提供了伪代码帮助理解。
576 2
|
机器学习/深度学习 算法 API
机器学习入门(五):KNN概述 | K 近邻算法 API,K值选择问题
机器学习入门(五):KNN概述 | K 近邻算法 API,K值选择问题
|
机器学习/深度学习 算法
机器学习入门(三):K近邻算法原理 | KNN算法原理
机器学习入门(三):K近邻算法原理 | KNN算法原理
|
机器学习/深度学习 算法 大数据
机器学习入门:梯度下降算法(下)
机器学习入门:梯度下降算法(下)
|
机器学习/深度学习 算法
机器学习入门:梯度下降算法(上)
机器学习入门:梯度下降算法(上)

热门文章

最新文章