Leetcode day09

数组双指针

双指针分为「对撞指针」、「快慢指针」、「分离双指针」。

  • 对撞指针:两个指针方向相反。适合解决查找有序数组中满足某些约束条件的一组元素问题、字符串反转问题。
  • 快慢指针:两个指针方向相同。适合解决数组中的移动、删除元素问题,或者链表中的判断是否有环、长度问题。
  • 分离双指针:两个指针分别属于不同的数组 / 链表。适合解决有序数组合并,求交集、并集问题。

344. 反转字符串

难度简单491

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。

示例 1:

输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]

示例 2:

输入:s = ["H","a","n","n","a","h"]
输出:["h","a","n","n","a","H"]

解题思路:使用两个指针指向数组头和尾,如果指向的字符不相等就进行交换,当left=right或left>right时停止交换。

代码:

class Solution:

    def reverseString(self, s: List[str]) -> None:

        """

        Do not return anything, modify s in-place instead.

        """

        left = 0

        right = len(s)-1

        if left==right: # 数组只有1个元素

            return

        while left

            if s[left]!=s[right]:

                s[left],s[right]=s[right],s[left]

            left += 1

            right -= 1

            

26. 删除有序数组中的重复项

难度简单2326

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

示例 1:

输入:nums = [1,1,2]
输出:2, nums = [1,2]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
示例 2:

输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。

解题思路:使用快慢指针求解,相同元素不复制。

代码:

class Solution:

    def removeDuplicates(self, nums: List[int]) -> int:

        if len(nums)<2:

            return len(nums)

        slow = 0

        fast = 1

        while fast

            if nums[slow]!=nums[fast]:

                slow += 1

                nums[slow]=nums[fast]

            fast += 1

        return slow+1

80. 删除有序数组中的重复项 II

难度中等602

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现两次 ,返回删除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

示例 1:

输入:nums = [1,1,1,2,2,3]
输出:5, nums = [1,1,2,2,3]
解释:函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。 不需要考虑数组中超出新长度后面的元素。

示例 2:

输入:nums = [0,0,1,1,1,1,2,3,3]
输出:7, nums = [0,0,1,1,2,3,3]
解释:函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。 不需要考虑数组中超出新长度后面的元素。

解题思路:1. 按照和上一题一样的思路,只不过加入FLAG=1判断元素是否已经重复过一次,并且下一次如果快慢指针的元素不同,重置FLAG=0。2. 运行发现使用快慢指针,运行速度不如评论区中取巧的方法(遍历有序的数组,去掉长度范围2外的重复元素)。

代码1:

class Solution:

    def removeDuplicates(self, nums: List[int]) -> int:

        if len(nums)<=2:

            return len(nums)

        slow = 0

        fast = 1

        flag = 0

        while fast

            if nums[slow]!=nums[fast]:

                flag = 0

                slow += 1

                nums[slow]=nums[fast]

                fast += 1

            elif flag==0:

                flag = 1

                slow += 1

                nums[slow]=nums[fast]

                fast += 1

            elif flag==1:

                fast += 1

        return slow+1

代码2:

class Solution:

    def removeDuplicates(self, nums: List[int]) -> int:

        i = 0

        for e in nums:

            if i < 2 or e != nums[i - 2]:

                nums[i] = e

                i += 1

        return i

你可能感兴趣的:(leetcode,算法,数据结构)