数据结构和算法三(数组--双指针类问题)

181 阅读3分钟

文章为学习笔记,非原创,侵删

利用两个或多个不同位置的指针,通过速度和方向的变换解决问题。注意这种技巧经常在排序数组中使用。

调整数组顺序,奇数位于前边,偶数位于后边

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分

思路

  • 假设有两个指针 start 和 end
  • start 从数组第一个出发向后遍历,end从数组最后一个触发向前遍历
  • 当start遍历到偶数,end遍历到奇数的时候,交换位置,否则继续遍历。 注意:start和end是两个独立的遍历,互不干扰
  • 当start>end的时候,完成

function reOrderArray(array) {
    if (Array.isArray(array)) {
        let start = 0;
        let end = array.length - 1;
        while (start < end) {
            while (array[start] % 2 === 1) {
                start++;
            }
            while (array[end] % 2 === 0) {
                end--;
            }
            if (start < end) {
                console.log("start: "+start+' end: '+end);
                [array[start], array[end]] = [array[end], array[start]]
            }
        }
    }
    return array;
}

和为N的两个数字

一个有序的递增数组和一个数字N,在数组中查找两个数字,两个数字的和为N,如果有多对这样的数字,则取乘积最小的两个

思路

可参照上一个题目,设置两个值start和end

  • 假设有两个指针 start 和 end
  • start 从数组第一个出发向后遍历,end从数组最后一个触发向前遍历。start++, end--
  • 判断 array[start]array[end]的和是否等于N
  • array[start]array[end]等于N,返回
  • array[start]array[end]小于N,说明array[start]的值太小,start++
  • array[start]array[end]大于N,说明 array[end]的值太大,end--
  • 如果 start == end 的时候还是没有等于N的,说明没有符合条件的结果
function FindNumbersWithSum(array, sum) {
  if (array && array.length > 0) {
    let left = 0;
    let right = array.length - 1;
    while (left < right) {
      const s = array[left] + array[right];
      if (s > sum) {
        right--;
      } else if (s < sum) {
        left++;
      } else {
        return [array[left], array[right]]
      }
    }
  }
  return [];
}

和为N的连续正整数序列

输入一个正整数N,所有和为N的连续正整数序列

例如:输入正整数15。 因为 1+2+3+4+5 = 4+5+6 = 7+8 = 15 所以打印出3个连续序列[1,2,3,4,5][4,5,6][7,8]

思路

  • 设定一个容器 child,初始值为[1,2]
  • 记录child的开头元素small和结尾元素big
  • 数组向右扩张,增加元素
  • big向右移动,child容器末尾增加一个数字
  • small向右移动,容器首位减少一个数
  • child的和小于目标值的时候,big向右移动
  • child的和大于目标值的时候,small向右移动
  • small的值大于big的时候,值太大类,没有符合要求的数组类,退出
function FindContinuousSequence(sum) {
  const result = [];
  const child = [1, 2];
  let big = 2;
  let small = 1;
  let currentSum = 3;
  while (big < sum) {
    while (currentSum < sum && big < sum) {
        child.push(++big);
        currentSum += big;
    }
    while (currentSum > sum && small < big) {
        child.shift();
        currentSum -= small++;
    }
    if (currentSum === sum && child.length > 1) {
        result.push(child.slice());
        child.push(++big);
        currentSum += big;
    }
  }
  return result;
}