美文网首页
算法1:双指针

算法1:双指针

作者: HYIndex | 来源:发表于2021-03-07 22:44 被阅读0次

双指针通常用在有序数组,链表的数据结构上,根据题目条件移动对应的指针。比如判断子串、链表是否有环的问题。

1.1 最长子串

LeetCode No.524

题目描述:给定一个字符串和一个字符串字典,找到字典里面最长的字符串,该字符串可以通过删除给定字符串的某些字符来得到。如果答案不止一个,返回长度最长且字典顺序最小的字符串。如果答案不存在,则返回空字符串
输入:
s = "abpcplea", d = ["ale","apple","monkey","plea"]
输出:
"apple"

思路:本题主要思路是要将删除s中某些字符后和targe匹配转化为判断是target是否为s的子串
判断是否为子串:使用双指针,如果当前字符相等,两个指针同时+1,否则只有母字符串的指针+1,最后判断目标字符传的指针是否等于其长度即可。
参考原文

示例代码:

func is_substr(s, target string) bool {
    j := 0
    for i := 0; i < len(s) && j < len(target); i++ {
        if s[i] == target[j] {
            j++
        }
    }
    return j == len(target)
}

func findLongestWord(s string, dictionary []string) string {
    var longest string
    for _, cur := range dictionary {
        // 如果当前字符串是s的子串,当当前字符串长度大于目前结果 或 长度相等但是当前串字典序排在前面时更新目前结果
        if is_substr(s, cur) && (len(cur) > len(longest) || len(cur) == len(longest) && cur < longest) {
            longest = cur
        }
    }
    return longest
}

1.2 两数之和

LeetCode No.167

题目描述:给定一个已按照 升序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]

思路:因为输入数组有序,那么可以用左右两个指针,初始位于两端,判断当前两数和如果大于target,那么right指针减一,如果小于target,left加一,如果等于就返回。

示例代码:

func twoSum(numbers []int, target int) []int {
    for left, right := 0, len(numbers) - 1; left < right; {
        cur := numbers[left] + numbers[right]
        if cur == target {
            return []int{left+1, right+1}
        }
        if cur < target {
            left++
        } else {
            right--
        }
    }
    return []int{}
}

1.3 判断链表是否存在环

LeetCode No.141

题目描述:给定一个链表,判断链表中是否有环。

思路:经典解法使用快慢指针,如果存在环两个指针一定会相遇,注意指针空的判断,避免出现野指针。

示例代码:

func hasCycle(head *ListNode) bool {
    if head == nil || head.Next == nil {
        return false
    }
    faster, slower := head.Next.Next, head.Next
    for faster != nil && faster.Next != nil && slower != nil {
        if faster == slower {
            return true
        }
        faster = faster.Next.Next
        slower = slower.Next
    }
    return false
}

1.4 接雨水

LeetCode No.42

题目描述:给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

思路:当前柱子能接的雨水数为其左右最高的柱子的较小值减当前柱子的高度

方法1:先求出每个柱子i左边的最大高度left_max[i],右边最大高度right_max[i],然后遍历一次计算。时间复杂度T = O(3n)

示例代码:

func trap(height []int) int {
    res, n := 0, len(height)
    if n == 0 {
        return res
    }
    left_max, right_max := make([]int, n), make([]int, n)
    left_max[0], right_max[n - 1] = height[0], height[n - 1]
    for i := 1; i < n; i++ {
        left_max[i] = max(left_max[i - 1], height[i])
    }
    for i := n - 2; i >= 0; i-- {
        right_max[i] = max(right_max[i + 1], height[i])
    }
    for i := 0; i < n; i++ {
        res += min(right_max[i], left_max[i]) - height[i]
    }
    return res
}

方法2:只需遍历一次的双指针解法,两个指针最终在最高点相遇。

示例代码:

func trap(height []int) int {
    res, left, right := 0, 0, len(height) - 1
    if right < 0 {
        return res
    }
    left_max, right_max := 0, 0
    for left < right {
        if height[left] > height[right] {
            right_max = max(right_max, height[right])
            res += right_max - height[right]
            right--
        } else {
            left_max = max(left_max, height[left])
            res += left_max - height[left]
            left++
        }
    }
    return res
}

相关文章

  • 算法1:双指针

    双指针通常用在有序数组,链表的数据结构上,根据题目条件移动对应的指针。比如判断子串、链表是否有环的问题。 1.1 ...

  • 【剑指offer-双指针】

    导读 算法 | 双指针套路总结 常用的双指针技巧 算法与数据结构基础 - 双指针 目录: 面试题04. 二维数组中...

  • LeetCode进阶977-双指针

    概要 双指针是一种比较常见的算法思想,在循环遍历数组时经常会用到。双指针主要有两种算法技巧:1、快慢指针(例如已发...

  • 环形链表

    2019年2月4日算法题 1,环形链表判断 (1)双指针法 双指针法的思想:定义fast、slow两个节点...

  • 滑动窗口算法

    一、滑动窗口算法 也会使用两个指针,但和双指针算法不同的是双指针算法关注的往往是两个指针正在指向的两个元素,而滑动...

  • 双指针算法

    元素:数组目标:求三数之和思路:数组遍历 首先对数组进行排序,排序后固定一个数 nums[i],再使用左右指针指向...

  • 『算法』『数据结构』 浅谈滑动窗口算法(思想)[双指针法中的左右

    基本认识 滑动窗口算法的本质是双指针法中的左右指针法,滑动窗口算法是双指针法中的左右指针法更为形象的一种表达方式。...

  • 2.(位、双指针、离散化、区间合并)

    1 .位运算 2. 双指针算法 3. 离散化 4. 区间合并

  • [Week1]双指针算法

    Week1/2 刷题 (7.9 - 7.23) 复杂度理论与双指针算法入门 必须熟练掌握的两个排序算法 二分法 三...

  • 双指针算法总结

    简介 双指针算法其实也可以称作是滑动窗口法,跟上一篇介绍的最长回文子串的介绍很相似,都是用两个指针来表示指针中间的...

网友评论

      本文标题:算法1:双指针

      本文链接:https://www.haomeiwen.com/subject/ujkrqltx.html