【LeetCode】双指针

本文详细介绍了利用双指针解决数组操作的问题,包括删除有序数组中的重复元素、求和问题如两数之和、三数之和、最接近的三数之和、四数之和,以及用左右指针维护子数组以找到最小长度的子数组、乘积小于K的子数组和最长山脉。还涵盖了两个有序数组的合并和交集问题。通过这些实例,展示了如何巧妙地运用双指针技巧解决数组算法问题。
摘要由CSDN通过智能技术生成

双指针场景

例题

原地修改数组

数据有序,一个指针(slow)用来维护结果集,一个指针(fast)来遍历

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

给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}

示例 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 。不需要考虑数组中超出新长度后面的元素。

提示:

0 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums 已按升序排列


思路:
因为是有序数组去重复元素,我们应该想到用两个同向的双指针 fast和slow,slow用来指向放置不重复元素的位置,fast指向当前遍历到的位置。
当fast指向的位置和前一个元素不相同时,就可以将此数复制到slow指向位置,slow后移。

class Solution {
    public int removeDuplicates(int[] nums) {

        // 不重复元素插入的位置
        int slow = 1;
        // 遍历到的位置
        int fast = 1;
        int n = nums.length;
        if (n == 0) {
            return 0;
        }
        while(fast<n){
            // fast和前一个元素不同,则移到slow处
            if(nums[fast]!=nums[slow-1]){
                nums[slow] = nums[fast];
                slow++;
            }
            // fast和前一个相同, 则继续向后走 即忽略
            fast++;
        }
        return slow;

    }
}

80. 删除有序数组中的重复项(删除k个重复元素)

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

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

说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:

// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);

// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}

示例 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 <= nums.length <= 3 * 10⁴
-10⁴ <= nums[i] <= 10⁴
nums 已按升序排列


思路:
i是保留的数组的位置,j是遍历nums数组的指针,判断当前j是否能保留就是看nums[j]和nums[i-k]是否相等

    public int removeDuplicates(int[] nums) {
        int n = nums.length;
        if (n<=2){
            return n;
        }
        int i = 2;
        for (int j = 2;j<n;j++){
            if (nums[j]!=nums[i-2]){
                nums[i] = nums[j];
                i++;
            }

        }
        return i;
    }

83.删除排序链表中的重复元素

给定一个已排序的链表的头
head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。
示例 1:
输入:head = [1,1,2]
输出:[1,2]

示例 2:
输入:head = [1,1,2,3,3]
输出:[1,2,3]


    public ListNode deleteDuplicates(ListNode head) {
        if (head==null){
            return null;
        }
        ListNode slow = head;
        ListNode fast = head;
        while (fast!=null){
            if (slow.val!=fast.val){
                slow.next = fast;
                slow = slow.next;
            }
            fast = fast.next;
        }
        slow.next = null;
        return head;
    }

27.移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。


    public int removeElement(int[] nums, int val) {
       int n = nums.length;
       int slow = 0;
       int fast = 0;
       while (fast<n){
           if (nums[fast]!=val){
               nums[slow++] = nums[fast];
           }
           fast++;
       }
       return slow;
   }

求和

这种求和问题 就是先排序,然后通过左右指针(left=0,right=n-1)移动 得到解
注意的就是去重复值
求和问题模板:团灭nSum问题

  • 模板是两数之和去重复值,后面n数之和就是固定一个值调用n-1数之和
  • 三数之和其实就是遍历nums[i],求两个数的和是target - nums[i],即在两数之和的基础上加了个for循环
  • 四数之和 就是固定一个值,求三数之和
    public int[] twoSum(int[] nums, int target) {
        // 1、没排好序的先排序
        Arrays.sort(nums);
        // 2、左右指针查找target
        int n = nums.length;
        int left = 0, right = n-1;
        // 答案:所有符合条件的元素值
        List<List<Integer>> ans = new ArrayList<>();
        while (left<right){
            int sum = nums[left] + nums[right];
            int leftValue = nums[left];
            int rightValue = nums[right];
            if (sum==target){
                List<Integer> curAns = new ArrayList<>();
                curAns.add(nums[left]);
                curAns.add(nums[right]);
                ans.add(curAns);
                // 去除重复值
                while (left<right && nums[left]==leftValue){
                    left++;
                }
                while (left<right && nums[right]==rightValue){
                    right--;
                }
            }else if(sum>target){
                // 去除重复值
                while (left<right && nums[right]==rightValue){
                    right--;
                }
            }else{
                // 去除重复值
                while (left<right && nums[left]==leftValue){
                    left++;
                }
            }
        }
        return ans;
    }

剑指 Offer 57. 和为s的两个数字

输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s。如果有多对数字的和等于s,则输出任意一对即可。

示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[2,7] 或者 [7,2]

示例 2:
输入:nums = [10,26,30,31,47,60], target = 40
输出:[10,30] 或者 [30,10]

限制:
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^6


思路: 注意做这种求和的 为了防止溢出应该用减的方式nums[l] == target-nums[r] 而不是加的方式

class Solution {
    public int[] twoSum(int[] nums, int target) {

        int l = 0,r = nums.length-1;
        while(l<r){
            if(nums[l]==target-nums[r]){
                return new int[]{nums[l],nums[r]};
            }
            else if(nums[l]<target-nums[r]){
                l++;
            }
            else{
                r--;
            }
        }
        return new int[0];
    }
}

15. 三数之和

15. 三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

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

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
示例 2:

输入:nums = []
输出:[]
示例 3:

输入:nums = [0]
输出:[]

提示:

0 <= nums.length <= 3000
-105 <= nums[i] <= 105


思路:
先排序 ,然后就可以用双指针
这个题要注意的是去重, 由于我们的数组是排好序的,所以我们可以在指针移动的时候判断和下一个值是否相等

    public List<List<Integer>> threeSum(int[] nums) {
        Arrays.sort(nums);
        List<List<Integer>> ans = new ArrayList<>();
        int n = nums.length;
        for (int i = 0; i < n; i++) {
            int left = i+1;
            int right = n-1;
            while(left<right){
                // 三数之和
                int sum = nums[i]+nums[left]+nums[right];
                // 左指针和右指针对应的值
                int lValue = nums[left];
                int rValue = nums[right];
                if(sum==0){
                    ArrayList<Integer> lst = new ArrayList<>();
                    lst.add(nums[i]);
                    lst.add(nums[left]);
                    lst.add(nums[right]);
                    ans.add(lst);
                    // 去重
                    while(left<right && lValue==nums[left]){
                        left++;
                    }
                    while(left<right && rValue==nums[right]){
                        right--;
                    }
                }
                else if(sum>0){
                    // 去重
                    while(left<right && rValue==nums[right]){
                        right--;
                    }
                }
                else{
                    // 去重
                    while(left<right && lValue==nums[left]){
                        left++;
                    }
                }
            }
            while(i<n-1 && nums[i]==nums[i+1]){
                i++;
            }
        }
        return ans;

    }

16. 最接近的三数之和

16. 最接近的三数之和

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

示例:

输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。

提示:

3 <= nums.length <= 10^3
-10^3 <= nums[i] <= 10^3
-10^4 <= target <= 10^4


思路:
同样是求三数之和,只是变成了最接近的,所以就算一下ans和sum 减target
得到最接近的
注意这个也是有重复值的,也要注意去重

    public int threeSumClosest(int[] nums, int target) {
        Arrays.sort(nums);
        int n = nums.length;
        int ans = 10000; // 注意不能写成MAX.Integer 因为这样-负的target会越界
        for(int i = 0;i<n;i++){

            int left =i+1;
            int right = n-1;

            while(left<right){
                int sum = nums[i]+nums[left]+nums[right];
                int leftValue = nums[left];
                int rightValue = nums[right];
                if(Math.abs(ans-target)>Math.abs(sum-target)){
                    ans = sum;
                }
                if(sum==target){
                    return ans;
                }
                else if(sum>target){
                    while(right>left && nums[right]==rightValue){
                        right--;
                    }

                }
                else{
                    while(right>left && nums[left]==leftValue){
                        left++;
                    }
                }
            }
            // 重复元素
            while(i<n-1 && nums[i]==nums[i+1]){
                i++;
            }
        }
        return ans;
    }

18. 四数之和

在三数之和的基础上加一层for循环
注意新加了溢出判断 所以在相加判断前要将nums[i]强转成long

class Solution {
    public List<List<Integer>> fourSum(int[] nums, int target) {
        Arrays.sort(nums);
        List<List<Integer>> ans = new ArrayList<>();
        int n = nums.length;
        // 固定一个值
        for (int i =0;i<n;i++){

            // 求三数之和 为nums[a]+nums[b]+nums[c] == target - nums[i]
            List<List<Integer>> threeAnsList = threeSum(nums,i+1,target - nums[i]);
            for (List<Integer> threeAns:threeAnsList){
                threeAns.add(nums[i]);
                ans.add(threeAns);
            }
            // 去重复值
            while (i<n-1 && nums[i]==nums[i+1]){
                i++;
            }
        }
        return ans;
    }

    public List<List<Integer>> threeSum(int[] nums, int start, int target) {

        List<List<Integer>> res = new ArrayList<>();
        int n = nums.length;


        for (int i = start; i < n; i++) {
            // -nums[i] == nums[j]+nums[k] 求两数之和是-nums[i]
            int left=i+1,right = n-1;
            while (left<right){
                int leftValue = nums[left];
                int rightValue = nums[right];
                if ((long)nums[left]+nums[right]+nums[i]==target){
                    // 答案
                    List<Integer> curAns = new ArrayList<>();
                    curAns.add(nums[i]);
                    curAns.add(leftValue);
                    curAns.add(rightValue);
                    res.add(curAns);
                    // 去重
                    while (left<right && nums[left]==leftValue){
                        left++;
                    }
                    while (left<right && nums[right]==rightValue){
                        right--;
                    }
                } else if((long)nums[left]+nums[right]+nums[i]>target){
                    // 去重
                    while (left<right && nums[right]==rightValue){
                        right--;
                    }
                }else {
                    // 去重
                    while (left<right && nums[left]==leftValue){
                        left++;
                    }
                }
            }
            // 去重
            while (i<n-1 && nums[i]==nums[i+1]){
                i++;
            }
        }

        return res;

    }
}

用左右指针维护子数组

这部分题目都是通过left和right来维护一个子数组,可行解有很多,下一个解可以在上一个可行解的基础上继续移动

209. 长度最小的子数组

209. 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:

输入:target = 4, nums = [1,4,4]
输出:1
示例 3:

输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0


思路:
通过left和right维护子数组的左右边界,没有达到条件右指针右移,达到条件后,左指针右移收缩

class Solution {
    public int minSubArrayLen(int target, int[] nums) {

        int n = nums.length;
        // left和right就是当前子数组的边界

        int ans = Integer.MAX_VALUE;

        
        int left = 0;
        int right = 0;
        // 当前窗口内的和
        int sum = nums[left];
        
        while(left<=right & right<n){

            // 没有达到条件,窗口右移
            if(sum<target){
                right++;
                if(right<=n-1)
                    sum+=nums[right];

            }else{ // 找到可行解
                ans = Math.min(ans,right-left+1);
                // 窗口左边界右移 缩小窗口
                sum-=nums[left];
                left++;
            }
        }

        return ans==Integer.MAX_VALUE?0:ans;
    }
}

题解的:

    class Solution {
        public int minSubArrayLen(int s, int[] nums) {
            int n = nums.length;
            if (n == 0) {
                return 0;
            }
            int ans = Integer.MAX_VALUE;
            int start = 0, end = 0;
            int sum = 0;
            while (end < n) {
                sum += nums[end];
                while (sum >= s) {
                    ans = Math.min(ans, end - start + 1);
                    sum -= nums[start];
                    start++;
                }
                end++;
            }
            return ans == Integer.MAX_VALUE ? 0 : ans;
        }
    }

713. 乘积小于K的子数组*

给定一个正整数数组 nums。

找出该数组内乘积小于 k 的连续的子数组的个数。

示例 1:

输入: nums = [10,5,2,6], k = 100
输出: 8
解释: 8个乘积小于100的子数组分别为: [10], [5], [2], [6], [10,5], [5,2], [2,6], [5,2,6]。
需要注意的是 [10,5,2] 并不是乘积小于100的子数组。
说明:

0 < nums.length <= 50000
0 < nums[i] < 1000
0 <= k < 10^6


思路:
自己做的时候没有想到这样
遍历right,找到满足的左边界。这样下一个right就可以用前一个right
在这里插入图片描述

    public int numSubarrayProductLessThanK(int[] nums, int k) {
        if(k<=1){
            return 0;
        }
        int left = 0;
        int mul = 1;
        int ans = 0;
        int n = nums.length;
        // 以right 为右边界,找到最小的left
        for (int right=0; right<n;right++){
            mul*=nums[right];
            // 向右移动left,得到满足条件的left
            while(mul>=k){
                mul /= nums[left++];
            }
            // 得到以当前right为右边界的 子数组的个数
            ans += right-left+1;
        }
        return ans;
    }

845.数组中的最长山脉

我们把数组 A 中符合下列属性的任意连续子数组 B 称为 “山脉”:

B.length >= 3
存在 0 < i < B.length - 1 使得 B[0] < B[1] < … B[i-1] < B[i] > B[i+1] > … > B[B.length - 1]
(注意:B 可以是 A 的任意子数组,包括整个数组 A。)

给出一个整数数组 A,返回最长 “山脉” 的长度。

如果不含有 “山脉” 则返回 0。

示例 1:

输入:[2,1,4,7,3,2,5]
输出:5
解释:最长的 “山脉” 是 [1,4,7,3,2],长度为 5。
示例 2:

输入:[2,2,2]
输出:0
解释:不含 “山脉”。

提示:

0 <= A.length <= 10000
0 <= A[i] <= 10000


思路:从右向左,先找单调递增,找到后再找单调递减

    public int longestMountain(int[] arr) {
        int n = arr.length;
        // 当前窗口的右边界
        int right =n-1;
        int ans = 0;

        while(right>=0){

            int cur = right;
            while(cur>0 && arr[cur-1]>arr[cur]){
                cur--;
            }
            // 已找到山脉右半部分
            if(cur<right){
                int mid = cur;
                // 找山脉的左半部分
                while(cur>0 && arr[cur-1]<arr[cur]){
                    cur--;
                }
                // 找到可行解
                if(cur<mid){
                    ans = Math.max(ans,right-cur+1);
                }
                right=cur;
            }
            else{ // 以此right为右边界的没有可行解
                right--;
            }
        }
        return ans;
    }

两个数组

对于两个有序数组,一人一个指针 进行比较

88. 合并两个有序数组

给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。

初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。你可以假设 nums1 的空间大小等于 m + n,这样它就有足够的空间保存来自 nums2 的元素。

示例 1:
输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]

示例 2:
输入:nums1 = [1], m = 1, nums2 = [], n = 0
输出:[1]

提示:
nums1.length == m + n
nums2.length == n
0 <= m, n <= 200
1 <= m + n <= 200
-109 <= nums1[i], nums2[i] <= 109


i: 从后往前遍历nums1,作为当前要填充的位置
l1,l2 分别指向各自的数组, 谁大就填谁
对于l2<0,说明l2已经都移到了nums1中 直接可以返回;当l1<0,要把nums2全部移过来。

    public void merge(int[] nums1, int m, int[] nums2, int n) {

        int l2 = n-1;
        int l1 = m-1;
        // 从后往前遍历,i指向当前要插入的位置
        for (int i = m+n-1; i >= 0; i--) {
            // nums2已经全部填到nums1中
            if(l2<0){
                return ;
            }
            // 谁大谁填进去
            if((l1>=0 && nums2[l2]>nums1[l1])||l1<0){
                nums1[i] = nums2[l2];
                l2--;
            }else{
                nums1[i] = nums1[l1];
                l1--;
            }
        }
    }

349. 两个数组的交集

给定两个数组,编写一个函数来计算它们的交集。

示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]
示例 2:
输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]

说明:
输出结果中的每个元素一定是唯一的。
我们可以不考虑输出结果的顺序。


思路:
由于不考虑输出结果的顺序,所以就把两个数组都排序,然后用分别用l1,l2对应两个数组 进行比较。 此外还要当前指针和前一个指针是否相同进行去重。

    public int[] intersection(int[] nums1, int[] nums2) {
        int n1 = nums1.length;
        int n2 = nums2.length;

        Arrays.sort(nums1);
        Arrays.sort(nums2);
        List<Integer> list = new ArrayList<>();

        int l1=0,l2=0;
        while(l1<n1 && l2<n2){
            if(nums1[l1]==nums2[l2]){
                list.add(nums1[l1]);
                l1++;
                l2++;
            }
            else if(nums1[l1]>nums2[l2]){
                l2++;
            }
            else{
                l1++;
            }


            while(l1>0 && l1<n1 &&nums1[l1]==nums1[l1-1]){
                l1++;
            }
            while(l2>0 && l2<n2 &&nums2[l2]==nums2[l2-1]){
                l2++;
            }
        }

        int n = list.size();
        int[] ans = new int[n];
        for (int i = 0; i < n; i++) {
            ans[i] = list.get(i);
        }
        return ans;
    }

题解的思路:
去重部分不一样,就是在往ans 添加的时候判断是否重复,否则就不添加

    public int[] intersection(int[] nums1, int[] nums2) {
        int n1 = nums1.length;
        int n2 = nums2.length;

        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int[] ans = new int[n1+n2];

        int l1=0,l2=0,l=0;
        while(l1<n1 && l2<n2){
            if(nums1[l1]==nums2[l2]){
                // 保证元素唯一性
                if(l==0 || nums1[l1]!=ans[l-1]){
                    ans[l++] = nums1[l1];
                }
                l1++;
                l2++;
            }
            else if(nums1[l1]>nums2[l2]){
                l2++;
            }
            else{
                l1++;
            }
        }

        return Arrays.copyOfRange(ans,0,l);
    }

922. 按奇偶排序数组 II

给定一个非负整数数组 A, A 中一半整数是奇数,一半整数是偶数。
对数组进行排序,以便当 A[i] 为奇数时,i 也是奇数;当 A[i] 为偶数时, i 也是偶数。
你可以返回任何满足上述条件的数组作为答案。

示例:

输入:[4,2,5,7]
输出:[4,5,2,7]
解释:[4,7,2,5],[2,5,4,7],[2,7,4,5] 也会被接受。

提示:

2 <= A.length <= 20000
A.length % 2 == 0
0 <= A[i] <= 1000


思路:

方法一:
用一个新数组,奇偶两个指针指向即将插入的位置

    public int[] sortArrayByParityII(int[] nums) {
        int n = nums.length;
        int[] ans = new int[n];
        int j = 1,o = 0;
        for (int i = 0; i < n; i++) {
            if(nums[i]%2!=0){
                ans[j] = nums[i];
                j+=2;
            }
            else{
                ans[o] = nums[i];
                o+=2;
            }
        }
        return ans;
    }

方法二:
原地,用奇偶两个指针,从前往后遍历偶数指针,如果当前数为奇数,则开始遍历奇数,直到奇数位置为偶数,就交换

    public int[] sortArrayByParityII(int[] nums) {

        int n = nums.length;
        int[] ans = new int[n];
        int j = 1;
        for (int i = 0; i < n; i=i+2) {
            // 是奇数就交换
            if(nums[i]%2==1){
                // 找到放置的奇数的位置
                while(nums[j]%2==1){
                    j+=2;
                }
                swap(nums,i,j);
            }
        }

        return nums;

    }


    public void swap(int[] nums, int i, int j){

        int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值