双指针入门

双指针入门级

判断是否为回文字符串(入门级)

要求:空间复杂度 O(1),时间复杂度 O(n)

function judge( str ) {
    // i, j 两个指针对撞,比较当前指针的值是否相同
    for(let i = 0, j = str.length - 1; i < Math.ceil(str.length / 2); i++, j--) {
        if (str[i] !== str[j]) {
            return false;
        }
    }
    return true;
}

反转字符串

function solve( str ) {
	// 首尾对撞指针,互换当前指针指向的值
    let head = 0, tail = str.length - 1;
    let res = str.split('');
    while(head < tail) {
        [res[head], res[tail]] = [res[tail], res[head]]
        head++;
        tail--;
    }
    return res.join('');
}

注意: 假设有一个字符串,想将第五个字符,替换成’-‘。因为字符串虽然可以像数组那样获取某一位置字符’Hello World’[4],但是不能像数组那样直接修改某一位置的字符’Hello World’[4] = ‘-’,这样是行不通的,但是可以把它切分成数组,修改某一位置的值,然后在合并回来。

最长无重复子数组

在这里插入图片描述

方法1: 队列 遇到重复的元素将队列中重复元素之前的元素出队

function maxLength( arr ) {
    // 队列 + hash 遇到重复的元素将队列中重复元素之前的元素出队
    const hash = {}, queue = [];
    let max = 0;
    for(let i = 0; i < arr.length; i++) {
        if (hash[arr[i]]) {
            let tmp;
            max = Math.max(queue.length, max);
            while(arr[i] !== tmp) {
                tmp = queue.shift();
                delete hash[tmp];
            }
        }
        hash[arr[i]] = 1;
        queue.push(arr[i]);
    }
    max = Math.max(queue.length, max);
    return max;
}

方法2: 同向指针,遇到重复元素时移动左指针至【已存在不重复列表中】重复元素的下一位

  • 该方法有一个最长用例未通过,未找到原因
function maxLength( arr ) {
    // 同向指针,遇到重复元素时移动左指针至【已存在不重复列表中】重复元素的下一位
    const hash = {};
    let l = 0, r = 0, max = 0;
    while(r < arr.length) {
        // hash存储不重复的连续元素
        if (hash[arr[r]]) {
            // 遇到重复元素
            // 先取Max,后移动l到重复元素下一位
            max = Math.max(max, r - l);
            while(arr[r] !== arr[l]) {
                l++;
                delete hash[arr[l]];
            }
            l++;
        } else {
            hash[arr[r]] = 1;
        }
        r++;
    }
    max = Math.max(max, r - l);
    return max;
}

盛水最多的容器

在这里插入图片描述

方法1: 暴力O(n^2)

function maxArea( height ) {
    // write code here
    let res = 0;
    for(let i = 0; i < height.length; i++) {
        for(let j = i + 1; j < height.length; j++) {
            let s = (j - i) * Math.min(height[i], height[j]);
            res = Math.max(res, s);
        }
    }
    return res;
}

方法2: 贪心思想

用对撞双指针向中间靠,这样底边长会缩短,因此还想要有更大容积只能是增加最短变长,此时我们每次指针移动就移动较短的一边,因为贪心思想下较长的一边比较短的一边更可能出现更大容积

function maxArea(height) {
    // write code here
    let res = 0;
    let l = 0,
        r = height.length - 1;
    // 贪心思想,每次指向较短边的指针向中间靠,另一指针不变。
    while (l < r) {
        let s = (r - l) * Math.min(height[r], height[l]);
        res = Math.max(res, s);
        if (height[l] < height[r]) {
            l++;
        } else {
            r--;
        }
    }
    return res;
}
  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值