力扣100——双指针

283. 移动0

bash 复制代码
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]

示例 2:
输入: nums = [0]
输出: [0]
 
提示:

1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
进阶:你能尽量减少完成的操作次数吗?
python 复制代码
class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        fast = 0
        slow = 0

        while fast < len(nums):
            if nums[fast] != 0:
                nums[slow] = nums[fast]
                slow+=1
            fast+=1
        
        while slow < len(nums): 
            nums[slow] = 0
            slow+=1
        return

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

bash 复制代码
给定一个已按照 升序排列  的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。

函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 0 开始计数 ,所以答案数组应当满足 0 <= answer[0] < answer[1] < numbers.length 。

假设数组中存在且只存在一对符合条件的数字,同时一个数字不能使用两次。

示例 1:
输入:numbers = [1,2,4,6,10], target = 8
输出:[1,3]
解释:2 与 6 之和等于目标数 8 。因此 index1 = 1, index2 = 3 。
示例 2:
输入:numbers = [2,3,4], target = 6
输出:[0,2]

示例 3:
输入:numbers = [-1,0], target = -1
输出:[0,1]
 

提示:

2 <= numbers.length <= 3 * 104
-1000 <= numbers[i] <= 1000
numbers 按 非递减顺序 排列
-1000 <= target <= 1000
仅存在一个有效答案
python 复制代码
class Solution:
    def twoSum(self, numbers: List[int], target: int) -> List[int]:
        # 注意数组是升序的,向右走变大,向左走变小
        left = 0
        right = len(numbers)-1

        while left != right:
            if numbers[left] + numbers[right] == target:
                break
            if numbers[left] + numbers[right] > target:
                right-=1
            if numbers[left] + numbers[right] < target:
                left+=1

        return [left, right]

15. 三数之和

bash 复制代码
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。

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

示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。

示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。

示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。
 

提示:

3 <= nums.length <= 3000
-105 <= nums[i] <= 105
python 复制代码
class Solution:
    def threeSum(self, nums: list[int]) -> list[list[int]]:
        ## 问题可以转换成nums[i] = -(nums[j]+nums[k]),
        # 进行排序,和两数之和II的问题思路一致
        nums.sort()
        ans = []
        n = len(nums)

        # 剪枝
        if nums[0]+nums[1]+nums[2]>0: return ans
        if nums[n-1]+nums[n-2]+nums[n-3]<0:return ans

        for i in range(len(nums)-2):
            target = nums[i]
            # 去除重复元素
            if i > 0 and target == nums[i-1]: continue
            j = i+1
            k = len(nums) - 1
            
            while j < k:
                s = target + nums[j] + nums[k]
                if  s > 0:
                    k-=1
                elif s < 0:
                    j+=1
                else:
                    ans.append([nums[i],nums[j],nums[k]])
                    j+=1
                    while j<k and nums[j]==nums[j-1]:
                        j+=1
                    k-=1
                    while j<k and nums[k] == nums[k+1]:
                        k-=1

        return ans               

11. 盛最多水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, heighti) 。

找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。

返回容器可以储存的最大水量。

说明:你不能倾斜容器。

示例 1:

输入:1,8,6,2,5,4,8,3,7

输出:49

解释:图中垂直线代表输入数组 1,8,6,2,5,4,8,3,7。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。

示例 2:

输入:height = 1,1

输出:1

提示:

n == height.length

2 <= n <= 10^5

0 <= heighti <= 10^4

python 复制代码
class Solution:
    def maxArea(self, height: List[int]) -> int:
        # 水容量=两条线之间的距离d✖️高度【min(两条线)】
        # 定义左右指针向中间移动
        left = 0
        right = len(height)-1
        # 向中间移动,当前的容量必定是短边h参与的所有容量中最大的:假设短边h不动,另一边向中间移动。
        # 因为向中间移动长度变小,要么另一边找到的大于这个短边h(短板效应面积变小),要么另一边移动后小于等于这个短边h,根据公式只会小于等于当前的面积,所以短边不动动另一边没有意义,应该移动短边。

        #因为移动短边,虽然距离d变小,但是高度有可能会变大,从而面积可能会变大
        max_area = 0
        while left < right:
            area = (right-left)*min(height[left], height[right])
            max_area = max(area, max_area)
            if height[left] < height[right]:
                left+=1
            else:
                right-=1
        return max_area

42. 接雨水

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

示例 1:

输入:height = 0,1,0,2,1,0,1,3,2,1,2,1

输出:6

解释:上面是由数组 0,1,0,2,1,0,1,3,2,1,2,1 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。

示例 2:

输入:height = 4,2,0,3,2,5

输出:9

提示:

n == height.length

1 <= n <= 2 * 10^4

0 <= heighti <= 10^5

把每块区域看做宽度为1的水桶,则每个水桶能接的雨水就是min(真正左右水板)-水桶的高度

所以我们需要求每个水桶的真正的左右水板(前后缀)

灵茶山爱府:

python 复制代码
class Solution:
    def trap(self, height: List[int]) -> int:
        n = len(height)
        # 创立两个数组,存储每个水桶的前后缀
        pre_max = [0] * n
        suf_max = [0] * n

        pre_max[0] = height[0]
        suf_max[n-1] = height[n-1]
        for i in range(1, n):
            pre_max[i] = max(pre_max[i-1], height[i])
        for i in range(n-2, -1, -1):
            suf_max[i] = max(suf_max[i+1], height[i])

        s = 0
        for h, pre, suf in zip(height, pre_max, suf_max):
            s+=min(pre, suf)-h

        return s        
相关推荐
Navigator_Z1 小时前
LeetCode //C - 1240. Tiling a Rectangle with the Fewest Squares
c语言·算法·leetcode
明志数科2 小时前
具身智能真机采集工程实践:5类高频失效模式与规避清单
人工智能·算法·机器学习
CSDN_RTKLIB2 小时前
空间哈希与拓扑缓存
算法
大熊背4 小时前
IspPipeline色相旋转模块实现
人工智能·算法·计算机视觉
爱学习的小白柏4 小时前
同城双活的核心不是双活,是逼着数据别出机房
大数据·人工智能·算法·langchain·ai编程
鹿角片ljp4 小时前
LeetCode 31:下一个排列|右找小,右找大,交换,右反转
java·数据结构·算法
橘子汽水1685 小时前
Leetcode 198,118打家劫舍,杨辉三角
算法·leetcode
LuminousCPP5 小时前
数据结构-排序(三):快速排序进阶|挖坑法、双指针交换与手动栈非递归实现
c语言·数据结构·笔记·算法·排序算法
数据知道6 小时前
国密算法实战——SM2/SM3/SM4 在国产系统中的应用
网络·算法·安全·网络安全·密码学·哈希算法