1、滑动窗口要素

双向指针,条件判断,暴力求解

2、模板

 

3、实例

167. 两数之和 II - 输入有序数组

给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。

函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。

说明:

返回的下标值(index1 和 index2)不是从零开始的。 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。 示例:

输入: numbers = [2, 7, 11, 15], target = 9 输出: [1,2] 解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

题解:双向指针

一个指针指向开头,一个指针指向结尾,如果a[l]+a[r]==target,返回[l+1,r+1];如果a[l]+a[r]<target,l+=1;如果a[l]+a[r]>target,r+=1

def f(a,target):
    l,r=0,len(a)-1
    while(l<r):
        s=a[l]+a[r]
        if(s==target):
            return [l+1,r+1]
        elif(s<target):
            l+=1
        else:
            r-=1
    return [-1,-1]

88. 合并两个有序数组

给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。

说明:

初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。  

示例:

输入: nums1 = [1,2,3,0,0,0], m = 3 nums2 = [2,5,6],       n = 3

输出:[1,2,2,3,5,6]

题解:

设置3个指针i,j,k,分别用i,j从后往前遍历nums1,nums2,k指针记录需要写入的位置

如果nums1[i]>nums2[j],nums1[k]=nums1[i],i-=1;否则nums1[k]=nums2[j],j-=1;k-=1

def f(a,b,m,n):
    i,j,k=m-1,n-1,m+n-1
    while(i>=0 and j>=0):
        if(a[i]>b[j]):
            a[k]=a[i]
            i-=1
        else:
            a[k]=b[j]
            j-=1
        k-=1
    
    while(j>=0):
        a[k]=b[j]
        j-=1
        k-=1
    return a

26. 删除排序数组中的重复项

给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

示例 1:

给定数组 nums = [1,1,2], 

函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 

你不需要考虑数组中超出新长度后面的元素。 示例 2:

给定 nums = [0,0,1,1,1,2,2,3,3,4],

函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。

你不需要考虑数组中超出新长度后面的元素。  

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝 int len = removeDuplicates(nums);

// 在函数里修改输入数组对于调用者是可见的。 // 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。 for (int i = 0; i < len; i++) {     print(nums[i]); }

题解:

设置两个指针i,j;i记录没有重复的数的位置,j向前遍历,直到遍历到数组的最后一个位置。

def f(a):
    i,j=0,1
    while(j<len(a)):
        if(a[j]!=a[i]):
            i+=1
            a[i]=a[j]
        j+=1
    return i+1

nums = [0,0,1,1,1,2,2,3,3,4]
r=f(nums)
print(nums[0:r])

514. 自由之路

电子游戏“辐射4”中,任务“通向自由”要求玩家到达名为“Freedom Trail Ring”的金属表盘,并使用表盘拼写特定关键词才能开门。

给定一个字符串 ring,表示刻在外环上的编码;给定另一个字符串 key,表示需要拼写的关键词。您需要算出能够拼写关键词中所有字符的最少步数。

最初,ring 的第一个字符与12:00方向对齐。您需要顺时针或逆时针旋转 ring 以使 key 的一个字符在 12:00 方向对齐,然后按下中心按钮,以此逐个拼写完 key 中的所有字符。

旋转 ring 拼出 key 字符 key[i] 的阶段中:

  1. 您可以将 ring 顺时针或逆时针旋转一个位置,计为1步。旋转的最终目的是将字符串 ring 的一个字符与 12:00 方向对齐,并且这个字符必须等于字符 key[i] 。
  2. 如果字符 key[i] 已经对齐到12:00方向,您需要按下中心按钮进行拼写,这也将算作 1 步。按完之后,您可以开始拼写 key 的下一个字符(下一阶段), 直至完成所有拼写。

示例:

 

滑动窗口算法java 实现简单 滑动窗口例题_字符串

输入: ring = "godding", key = "gd" 输出: 4 解释: 对于 key 的第一个字符 'g',已经在正确的位置, 我们只需要1步来拼写这个字符。 对于 key 的第二个字符 'd',我们需要逆时针旋转 ring "godding" 2步使它变成 "ddinggo"。 当然, 我们还需要1步进行拼写。 因此最终的输出是 4。

提示:

  1. ring 和 key 的字符串长度取值范围均为 1 至 100;
  2. 两个字符串中都只有小写字符,并且均可能存在重复字符;
  3. 字符串 key 一定可以由字符串 ring 旋转拼出。

题解:设置两指针,指针i循环遍历ring,指针j遍历key

 

32. 最长有效括号

给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。

示例 1:

输入: "(()" 输出: 2

解释: 最长有效括号子串为"()"

示例 2: 输入: ")()())" 输出: 4

解释: 最长有效括号子串为"()()"

题解:

设定一个栈q遍历字符串,设定一个max_len记录最大匹配数据,如果是')',出栈,如果栈为空,下标进栈,如果不为空,max_len=max(max_len,i-q.top());

否则下标继续进栈

def f(s):
    q=[-1]
    max_len=0
    k=0
    while(k<len(s)):
        if(s[k]==')'):
            q.pop()
            if(q):
                max_len=max(max_len,k-q[-1])
            else:
                q.append(k)
        else:
            q.append(k)
        k+=1
    return max_len