数组双指针-分离指针(三)

一、分离指针

分离双指针是双指针技术的一种应用,通常用于将链表或数组分割成两部分,通过两个指针控制分割点。

分离双指针一般用于处理有序数组合并,求交集、并集问题。

java模版

# 初始化两个指针,分别指向两个数组的起始位置
left_1, left_2 = 0, 0

# 当两个指针都未遍历到各自数组末尾时,循环进行比较
while left_1 < len(nums1) and left_2 < len(nums2):
    if 满足条件 1:
        # 通常表示两个指针指向的元素相等
        # 此时可以将该元素加入结果集(如交集),并同时移动两个指针
        left_1 += 1
        left_2 += 1
    elif 满足条件 2:
        # 通常表示第一个数组当前元素较小
        # 只移动第一个指针,继续比较下一个元素
        left_1 += 1
    elif 满足条件 3:
        # 通常表示第二个数组当前元素较小
        # 只移动第二个指针,继续比较下一个元素
        left_2 += 1
349. 两个数组的交集

349. 两个数组的交集https://leetcode.cn/problems/intersection-of-two-arrays/

    /**
     * 题目名称:349. 两个数组的交集
     * 题目编号:349. Intersection of Two Arrays
     * 难度:简单
     * 题目要求:给定两个数组,编写一个函数来计算它们的交集。并且返回他们对交集。
     * 思路:排序+分离指针。
     */
    @DataProvider(name = "intersection")
    public Object[][] intersection() {
        return new Object[][] {
                {new int[]{1,2,2,1}, new int[]{2,2}},
                {new int[]{4,9,5}, new int[]{9,4,9,8,4}}
        };
    }
    @Test(dataProvider = "intersection")
    public void testIntersection(int[] nums1, int[] nums2) {
        // 将俩个数组排序
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        // 分离指针
        int left_1 = 0; // 指针 1
        int left_2 = 0; // 指针 2
        int[] res = new int[nums1.length + nums2.length]; // 结果数组
        int index = 0;
        while (left_1 < nums1.length && left_2 < nums2.length) {
           if (nums1[left_1] == nums2[left_2]) {
              // 加入结果数组, 这里需要去重,只有 res 为空或当前元素与上一个加入的元素不同才加入结果,避免重复
               if (index == 0 || nums1[left_1] != res[index - 1]) {
                   res[index++] = nums1[left_1];
               }
               left_1++;
               left_2++;
           } else if (nums1[left_1] < nums2[left_2]) {
               left_1++;
           } else {
               left_2++;
           }
        }
        System.out.println(Arrays.toString(res));
//        return res;
    }

练习:350. 两个数组的交集 II

925. 长按键入

925. 长按键入https://leetcode.cn/problems/long-pressed-name/

    /**
     * 题目名称:925. 长按键入
     * 题目编号:925. Long Pressed Name
     * 难度:简单
     * 题目要求:
     * 你的朋友正在使用键盘输入他的名字 name。偶尔,在键入字符 c 时,按键可能会被长按,而字符可能被输入 1 次或多次。
     * 你将会检查键盘输入的字符 typed。如果它对应的可能是你的朋友的名字(其中一些字符可能被长按),那么就返回 True。
     * 解题思路:
     * 使用双指针,指针 1 指向 name,指针 2 指向 typed。
     */
    @DataProvider(name = "isLongPressedName")
    public Object[][] isLongPressedName() {
        return new Object[][] {
                {"alex", "aaleex"},
                {"saeed", "ssaaedd"},
                {"leelee", "lleeelee"},
                {"laiden", "laiden"},
        };
    }
    @Test(dataProvider = "isLongPressedName")
    public void testIsLongPressedName(String name, String typed) {
        int i = 0; // 指针 1
        int j = 0; // 指针 2
        while(j < typed.length()){
            if (i < name.length() && name.charAt(i) == typed.charAt(j)) {
                i++;
                j++;
            } else if (j > 0 && typed.charAt(j) == typed.charAt(j - 1)) {
                j++;
            } else {
                System.out.println(false);
                return;
            }
        }
        System.out.println(i == name.length());
    }
392. 判断子序列

392. 判断子序列https://leetcode.cn/problems/is-subsequence/

    /**
     * 题目名称:392. 判断子序列
     * 题目编号:392. Is Subsequence
     * 难度:简单
     * 题目要求:
     * 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。
     * 解题思路:
     * 使用双指针,指针 1 指向 s,指针 2 指向 t。
     */
    @DataProvider(name = "isSubsequence")
    public Object[][] isSubsequence() {
        return new Object[][] {
                {"abc", "ahbgdc"},
                {"axc", "ahbgdc"},
        };
    }
    @Test(dataProvider = "isSubsequence")
    public void testIsSubsequence(String s, String t) {
        int i = 0; // 指针 1
        int j = 0; // 指针 2
        while(i < s.length() && j < t.length()) {
            if (s.charAt(i) == t.charAt(j)) {
                i++;
                j++;
            } else {
                j++;
            }
        }
        System.out.println(i == s.length());
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值