zoukankan      html  css  js  c++  java
  • 前端程序员学好算法系列(二)数组

    我们今天继续研究数组在算法中的应用

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

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

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

    说明:

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

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

    我们这里直接用滑动窗口进行解题:


    1.定义左指针 l为0
    2.定义右指针为numbers.length - 1
    3.如果左指针的值和右指针的值相加等于target直接返回索引加1的值,否则大于时r-- 小于时l++

    var twoSum = function(numbers, target) {
          let l = 0
          let r = numbers.length - 1
          while(l<r){
              if(numbers[l]+numbers[r]==target){  
                  return [l+1,r+1]
              }
              if(numbers[l]+numbers[r]>target){
                  r--
              }else{
                  l++
              }    
          }
          return []
    };

    209. 长度最小的子数组
    给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

    示例:

    输入:s = 7, nums = [2,3,1,2,4,3]
    输出:2
    解释:子数组 [4,3] 是该条件下的长度最小的子数组。

    解题:
    1.设置[l,r] 左闭右闭的区间内取值,r区间默认为-1就是没有任何元素,res初始为数组的长度加1因为我们是取最小值,数组满足条件的值不可能大于数组长度加1
    2.我们在l和r的区间内重复取值,当区间内的值相加满足大于s时减掉最左边的一个元素,sum<s时让r++同时sum加上r的值。
    3.为保证数组不越界在r++前需要保证r+1< nums.length
    4.每次有解时计算区间内的元素数量为 r - l +1 ,+1是因为索引是从0开始的,取有正确答案时的最小元素个数
    5.当计算结果的长度为nums.length +1 时说明我们没有找到正确的解直接返回0

    var minSubArrayLen = function(s, nums) {
        let l = 0, r = -1 // [l, r], 左闭右闭
        let sum = 0  //初始化总和的值
        let res = nums.length + 1   //初始化可能的最大值加1
        while(l < nums.length){
            if((r+ 1 <nums.length) && sum < s){
                r++
                sum += nums[r]
            } else {
                sum -= nums[l]
                l++
            }
            if(sum >= s ){
                res = Math.min(res,r-l+1)
            }
            
        }
        if(res === nums.length + 1){
            return 0
        }
        return res
    }

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

    示例 1:

    输入: "abcabcbb"
    输出: 3 
    解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3

    示例 2:

    输入: "bbbbb"
    输出: 1
    解释: 因为无重复字符的最长子串是 "b",所以其长度为 1

    解题:

    1.滑动窗口问题 我们在 [ans,rk]区间内取值,初始化ans为0 ,rk为-1 ,-1是为了保证滑动窗口中没有值
    2.我们创建一个set结构判断我的的窗口中是否出现了重复的元素,当occ.has(s.charAt(rk + 1))不存在当前字符时右区间rk++,

    3.rk+1时保证数组不越界

    var lengthOfLongestSubstring = function(s) {
        // 哈希集合,记录每个字符是否出现过
        const occ = new Set();
        const n = s.length;
        // 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动
        let rk = -1, ans = 0;
        for (let i = 0; i < n; ++i) {
            if (i != 0) {
                // 左指针向右移动一格,移除一个字符
                occ.delete(s.charAt(i - 1));
            }
            while (rk + 1 < n && !occ.has(s.charAt(rk + 1))) {
                // 不断地移动右指针
                occ.add(s.charAt(rk + 1));
                ++rk;
            }
            // 第 i 到 rk 个字符是一个极长的无重复字符子串
            ans = Math.max(ans, rk - i + 1);
        }
        return ans;
    };
  • 相关阅读:
    C# DataGridView 与 datatable 之间数据传递
    C# 调用命令行命令 net use
    C# 链接 sql server 数据库字符串
    winform窗口关闭,进程没有关掉的解决办法
    select 中的逻辑判断 sql server
    C#中的abstract 类和方法!!!
    c# ComboBox绑定枚举
    C#与C++类型互转
    DllImport
    TCP三次握手四次挥手详解
  • 原文地址:https://www.cnblogs.com/kbnet/p/13380576.html
Copyright © 2011-2022 走看看