프런트엔드 알고리즘 이중 포인터

이중 포인터

이중 포인터는 배열이나 연결 목록의 문제를 해결하는 데 자주 사용되는 프로그래밍 기술입니다.

이중 포인터 방법은 두 개의 포인터(종종 빠른 포인터와 느린 포인터라고 함)를 사용하여 데이터 구조를 탐색하여 특정 요소를 찾거나 다른 복잡한 작업을 수행해야 하는 일부 문제를 해결합니다.

2포인터 방법의 가장 큰 장점은 역방향 탐색이나 다른 추가 데이터 구조를 사용할 필요 없이 단일 탐색으로 문제를 해결한다는 것입니다.

이렇게 하면 일부 문제를 해결하는 데 더 효율적이 됩니다.

: 배열에서 특정 값과 동일한 두 숫자의 합을 찾으려면 이중 포인터 방법을 사용할 수 있습니다.

  • 먼저, 배열의 시작 부분에 하나의 포인터를 배치하고 배열의 끝에 다른 포인터를 배치할 수 있습니다.

  • 그런 다음 두 포인터를 가운데로 이동하고 포인터가 가리키는 요소의 합을 대상 값과 비교할 수 있습니다.

    • 합계가 목표 값보다 크면 느린 포인터를 안쪽으로 이동합니다.
    • 합계가 목표 값보다 작으면 빠른 포인터를 바깥쪽으로 이동합니다.
    • 합이 목표 값과 같으면 두 요소를 찾은 것입니다.

2점 방법이 항상 모든 문제에 적합한 것은 아니며 그 사용은 문제의 특정 성격과 요구 사항에 따라 달라집니다 .

이중 포인터 방법을 사용할 때 잘못된 결과나 무한 루프를 방지하려면 문제의 요구 사항과 포인터 이동 조건을 이해해야 합니다.

분류

빠르고 느린 포인터(동일한 방향)

–> --> 빠르고 느린 포인터

a -> b -> c -> d -> a 링인지 확인하는 방법

반대쪽 포인터와 뒤쪽 포인터

자세한 내용을 보려면 WeChat에서 " 前端爱好者"를 검색 하고 나를 클릭하여 확인 하세요 .

예: 가장 가까운 세 숫자의 합

길이 n의 정수 배열 nums와 목표 값 target이 제공됩니다. 합계가 목표에 가장 가까워지도록 숫자에서 세 개의 정수를 선택하세요.

이 세 숫자의 합을 반환합니다.

각 입력 세트에 대해 정확히 하나의 솔루션이 있다고 가정합니다.

예시 1:

입력: nums = [-1,2,1,-4], target = 1
출력: 2
설명: target에 가장 가까운 합계는 2(-1 + 2 + 1 = 2)입니다.

예 2:

입력: 숫자 = [0,0,0], 대상 = 1
출력: 0

주소 : https://leetcode.cn/problems/3sum-closest/

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var threeSumClosest = function(nums, target) {
    
    
  // 1. 先排序
  // target - for 循环的数
  // -> <-
  let length = nums.length
  let res = Number.MAX_SAFE_INTEGER // 取无穷大数
  nums.sort((a,b) => a -b)

  for(let i = 0; i < length; i ++ ){
    
     // 复杂度:n+1
    // 依次获取其中元素
    // nums [i] + nums [a] + nums [b] = target  其中 nums [i] 确定;nums [a] + nums [b] 不确定
    // nums [i] + nums [i + 1] + nums [length - 1] = target

    let left = i + 1 // 复杂度:n
    let right = length - 1 // 复杂度:n

    // 两数之和判断

    while(left < right) {
    
     // 复杂度:n
      let sum = nums[i] + nums[left] + nums[right]

      if(Math.abs(sum - target) < Math.abs(res - target)){
    
    
        res = sum
      }

      if(sum < target){
    
    
        left ++ 
      } else if(sum > target){
    
    
        right --
      } else {
    
    
        return sum
      }
    }
  }

  return res 
};

예: 문자를 제거하여 사전에서 가장 긴 단어 일치

문자열 s와 문자열 배열 사전이 주어지면, s에서 일부 문자를 삭제하여 얻을 수 있는 사전에서 가장 긴 문자열을 찾아서 반환합니다.

답변이 두 개 이상인 경우 길이가 가장 길고 알파벳 순서가 가장 작은 문자열을 반환합니다. 답변이 없으면 빈 문자열이 반환됩니다.

예시 1:

입력: s = "abpcplea", Dictionary = ["ale","apple","monkey","plea"]
출력: "apple"

예 2:

입력: s = "abpcplea", 사전 = ["a", "b", "c"]

출력: "a"

힌트:

  • 1 <= s.길이 <= 1000
  • 1 <= 사전.길이 <= 1000
  • 1 <= 사전[i].length <= 1000
  • s와 Dictionary[i]는 영문 소문자로만 구성됩니다.
/**
 * @param {string} s
 * @param {string[]} dictionary
 * @return {string}
 */
var findLongestWord = function(s, dictionary) {
    
    
    let left = 0
    let right = 0
    let str = ''

    for(let i = 0; i < dictionary.length ; i ++ ){
    
    
        left = 0
        right = 0

        while(left < s.length && right < dictionary[i].length){
    
    
            if(s.charAt(left) === dictionary[i].charAt(right)){
    
    
                right ++
            }
            // 当此时长度一样
            if(right === dictionary[i].length){
    
    
                // 拿着dictionary[i]的长度 跟已有的之前的str的结果长度比较
                if(dictionary[i].length > str.length || (dictionary[i].length === str.length && dictionary[i] < str)){
    
    
                    str = dictionary[i]
                }
            }

            left ++;
        } 
    }

    return str
};

Guess you like

Origin blog.csdn.net/BradenHan/article/details/135258442