双指针问题

本文探讨了双指针技术在处理数组问题中的两种常见情况:快慢指针和收尾指针。快慢指针常用于排序和移除元素,如根据二进制中1的数目排序数组;而收尾指针则适用于回文和对称性判断。以删除排序数组中的重复项为例,原地修改数组并保持O(1)额外空间复杂度。在解决两数之和的问题中,利用有序数组特性,采用快慢指针从中间开始搜索,避免无效计算,确保找到唯一答案。
摘要由CSDN通过智能技术生成

双指针一般有两种case:

1. 快慢指针,一般排序需要使用快慢指针,快慢指针有两种游走方式:1.快指针一直往前,不归位;2. 慢指针移动时,快指针归位。

2. 收尾指针,一般回文、对称性判断需要使用首尾指针

 

双指针中,快慢指针问题:

1. 指针一快一慢,快指针按序遍历数组,慢指针记录有效数据位置。

2. 当快指针找到有效数据时,慢指针才往前走一步;

 

移除元素

给你一个整数数组 arr 。请你将数组中的元素按照其二进制表示中数字 1 的数目升序排序。

如果存在多个数字二进制中 1 的数目相同,则必须将它们按照数值大小升序排列。

请你返回排序后的数组

/**
 * @param {number[]} nums
 * @param {number} val
 * @return {number}
 */
var removeElement = function(nums, val) {
   let curIndex = 0;
   for(let compareIndex = 0; compareIndex< nums.length; compareIndex++){
       if(nums[compareIndex] !==val){
          nums[curIndex++] = nums[compareIndex]; 
       }
   }
   return curIndex;
};

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

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

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

/**
 * @param {number[]} nums
 * @return {number}
 */
var removeDuplicates = function(nums) {
    let curIndex =0 ;    
    // 注意是有序的数组,所以游走指针可以一直向前走。
    for(let compareIndex=1; compareIndex < nums.length; compareIndex++)
    {
        if(nums[curIndex] !== nums[compareIndex]){
            nums[++curIndex] = nums[compareIndex];
        }
    }
    return curIndex+1;
};

 

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

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

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

说明:

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

 

答题思路:

1.  数组是有序的,从大到小。 因此当某个值和第一个值的和大于target时,这个值右边及本身都不用考虑了,跟谁加都会大于目标值。只用考虑这个值左边的数据,因此要先找到这个中介值的index。

2.  快慢指针从中介值开始从右往左移动。 慢指针值是当前大值,快指针移动寻找一个小值与其相加。

若相机大于目标值,则快指针继续向左移动寻找更小的值;

若相加小于目标值,说明当前固定的大值无匹配小值与之相加可得目标值,因此直接向左移动慢指针换固定值,快指针指回慢指针的下一步,重新开始寻找小值;

若相等,则为返回快慢指针位置。注意要加1,因为题目要求索引不是从0开始

 

/**
 * @param {number[]} numbers
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(numbers, target) {
    let maxIndex = numbers.findIndex(num =>  num + numbers[0]> target);
    if(maxIndex === -1) maxIndex = numbers.length;
    secondIndex = maxIndex - 1;
    firstIndex = secondIndex-1;

    while(secondIndex >0){
        if(firstIndex<0){
            secondIndex--;
            firstIndex= secondIndex-1;
        }else{
            const total = numbers[firstIndex] + numbers[secondIndex];
            if(total < target){
                secondIndex --;
                firstIndex= secondIndex-1;
            }else if(total > target){
                firstIndex--;
            }else{
                return [firstIndex+1, secondIndex+1];
            }
        } 
    }
    return [];
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值