美文网首页
双指针问题

双指针问题

作者: 明年决赛小牛打雄鹿 | 来源:发表于2019-02-14 15:25 被阅读0次

    题目详细说明请自行到题库 - 力扣 (LeetCode)搜寻题号

    1. 两数和

    利用数组的有序,使用两个指针,一个为l,指向数组开头,一个为r,指向数组结尾;

    和大于target时右边指针左移一个,获得比当前小的下一个和;

    和小于target时左边指针右移一个,获得比当前大的下一个和;

    循环条件为 l < r ,循环结束时就把所有的和都遍历了一遍, 时间复杂度为O(n);

    167. Two Sum II - Input array is sorted

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

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

    class Solution:

        def twoSum(self, numbers, target):

            """

            :type numbers: List[int]

            :type target: int

            :rtype: List[int]

            """

            if len(numbers) < 2:

                return None

            l = 0

            r = len(numbers) - 1

            while l < r:

                s = numbers[l] + numbers[r]

                if s == target:

                    #这道题下标从1开始的

                    return [l + 1, r + 1]

                elif s < target:

                    l += 1

                else:

                    r -= 1

            return None

    2. 扩展, 三数和

    怎么把三数和转化为两数和呢?

    我们可以遍历一次数组取每一个 nums[i] ,使三数和等于target相当于

    在 nums[ i + 1 : ] 中找两个下标 l , r 使 nums[l] + nums[r] == target - nums[i]

    这样就转化为两数和问题, 时间复杂度为 O(n²) , 注意去除重复答案

    15. 3Sum

    给定一个包含 n 个整数的数组nums,判断nums中是否存在三个元素 a,b,c ,使得a + b + c = 0 ?找出所有满足条件且不重复的三元组。

    注意:答案中不可以包含重复的三元组。

    class Solution:

        def threeSum(self, nums):

            """

            :type nums: List[int]

            :rtype: List[List[int]]

            """

            #先排序

            nums.sort()

            res = []

            #current标记用于去重

            current = '-1'

            for i, value in enumerate(nums):

                if current == value:

                    continue

                current = value

                l = i + 1

                r = len(nums) - 1

                while l < r:

                    s = nums[i] + nums[l] + nums[r]

                    if s == 0:

                        res.append([nums[i],nums[l],nums[r]])

                        l += 1

                        r -= 1

                        #去掉重复l

                        while l < r and nums[l] == nums[l - 1]:

                            l += 1

                        #去掉重复r

                        while r > l and nums[r] == nums[r + 1]:

                            r -= 1

                    elif s < 0:

                        l += 1

                    else:

                        r -= 1

            return res

    还有一道4数和的题目, 思路是一样的, 再加一层循环, 时间复杂度为 O(n³)

    3. 盛水最多容器

    用双指针做,取2个指针,最左 l 和最右 r , 计算两块板装的面积

    当 l 的板比 r 的高时 , r -= 1

    当 r 的板比 l 的高时,  l += 1

    双指针遍历相当于求每个宽度下的最大面积, 从中取一个最大值, 时间复杂度为O(n)

    11. Container With Most Water

    给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i,ai) 。在坐标内画 n 条垂直线,垂直线 i的两个端点分别为 (i,ai) 和 (i, 0)。找出其中的两条线,使得它们与x轴共同构成的容器可以容纳最多的水。

    说明:你不能倾斜容器,且n的值至少为 2。

    class Solution:

        def maxArea(self, height):

            """

            :type height: List[int]

            :rtype: int

            """

            res = 0

            l, r = 0, len(height) - 1

            while l < r:

                #求面积, 等于宽度乘以 l , r 中高度比较小的那个值

                res = max(res, (r - l) * min(height[l],height[r]))

                if height[l] > height[r]:

                    r -= 1

                else:

                    l += 1

            return res

    4. 搜寻二维矩阵

    使用两层循环搜索时间复杂度为O(n²) , 而且没用到题目给的有序的条件

    我们可以假设右上角的值 matrix[x][y] 为初始值, 其中 x = 0 , y = n

    当matrix[x][y]  < target时,  说明 matrix[x] 这一行上的值都比 target 小, x += 1

    当matrix[x][y] > target时, 说明matrix在y这一列上的值都比target 大, y -= 1

    找到target时返回True, 超出矩阵后返回False  时间复杂度为 O(m + n)

    240. Search a 2D Matrix II

    编写一个高效的算法来搜索n矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:

    每行的元素从左到右升序排列。

    每列的元素从上到下升序排列。

    class Solution:

        def searchMatrix(self, matrix, target):

            """

            :type matrix: List[List[int]]

            :type target: int

            :rtype: bool

            """

            #判断矩阵有没有值

            x = len(matrix)

            if x == 0:

                return False

            y = len(matrix[0])

            if y == 0:

                return False

            #y取最后一列的下标

            y -= 1

            i = 0

            while i < x and y >= 0:

                if matrix[i][y] < target:

                    i += 1

                elif matrix[i][y] > target:

                    y -= 1

                else:

                    return True

            return False

    相关文章

      网友评论

          本文标题:双指针问题

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