1、LeetCode---数组

本文深入探讨了数组处理及双指针技巧的应用,包括二分查找、移动零元素、删除重复项等经典算法实现,并提供了详细的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、数组

第1部分

  • 明确变量含义
  • 循环不变量
  • 小数据量调试
  • 大数据量调试

1.1 二分查找

方法一:闭区间查找

class Solution {
public:
    int binarySearch1(vector<int> &nums, int n, int target) {
        int l = 0, r = n - 1;//闭区间查找
        while (l <= r) {
            int mid = l + (r - l) / 2;
            if (nums[mid] == target)
                return mid;
            if (nums[mid] > target)
                r = mid - 1;
            else
                l = mid + 1;
        }
        return -1;
    }
};

方法二:开区间查找

class Solution {
public:
    int binarySearch2(vector<int> &nums, int n, int target) {
        int l = 0, r = n;//开区间查找
        while (l < r) {
            int mid = l + (r - l) / 2;
            if (nums[mid] == target)
                return mid;
            if (nums[mid] > target)
                r = mid;
            else
                l = mid + 1;
        }
        return -1;
    }
};

1.2 LeetCode 283. 移动零

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

示例:

输入: [0,1,0,3,12]
输出: [1,3,12,0,0]

说明:

  • 必须在原数组上操作,不能拷贝额外的数组。
  • 尽量减少操作次数。

方法一:辅助空间移动

class Solution {
public:
    void moveZeroes(vector<int> &nums) {
        vector<int> nonZeroEle;
        for (int i = 0; i < nums.size(); i++)
            if (nums[i] != 0) nonZeroEle.push_back(nums[i]);
        for (int i = 0; i < nonZeroEle.size(); i++)
            nums[i] = nonZeroEle[i];
        for (int i = nonZeroEle.size(); i < nums.size(); i++)
            nums[i] = 0;
    }
};

方法二:原地移动

class Solution {
public:
    void moveZeroes(vector<int> &nums) {
        int k = 0;  // [0..k) / [0..k-1] 区间中都是非零元素
        for (int i = 0; i < nums.size(); i++) {  //循环不变,依旧保证[0..k)区间中都是非零元素
            if(nums[i]!=0) {
                nums[k]=nums[i];
                k++;
            }
        }
        for (int i = k; i < nums.size(); i++)
            nums[i]=0;
    }
};

方法三:交换移动

class Solution {
public:
    void moveZeroes(vector<int> &nums) {
        int k = 0;  // [0..k) / [0..k-1] 区间中都是非零元素
        for (int i = 0; i < nums.size(); i++) {  //循环不变,依旧保证[0..k)区间中都是非零元素
            if(nums[i]!=0)
                swap(nums[k++],nums[i]);
        }
    }
};

1.3 LeetCode 27. 移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1:

给定 nums = [3,2,2,3], val = 3,

函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。

你不需要考虑数组中超出新长度后面的元素。

示例 2:

给定 nums = [0,1,2,2,3,0,4,2], val = 2,

函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。

注意这五个元素可为任意顺序。
你不需要考虑数组中超出新长度后面的元素。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

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

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

代码:

class Solution {
public:
    int removeElement(vector<int> &nums, int val) {
        int i = 0;//[0,i) / [0,i-1] 不包含val
        int n = nums.size() - 1; //查找区间[i,n]
        while (i <= n) {
            while (i <= n&&nums[i] != val) i++;
            while (i <= n&&nums[n] == val) n--;
            if (i <= n) swap(nums[i++], nums[n--]);
        }
        return i;
    }
};

1.4 LeetCode 26. 删除排序数组中的重复项

给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

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

示例 1:

给定数组 nums = [1,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。

你不需要考虑数组中超出新长度后面的元素。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

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

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

代码:

class Solution {
public:
	int removeDuplicates(vector<int>& nums) {
		if (nums.size() == 0) return {};
		
		int j = 1;
		for (int i = 1; i < nums.size(); i++)
		{
			if (nums[i] != nums[i-1]) 
			{
				nums[j] = nums[i];
				j++;
			}
		}
		return j ;
	}
};

1.5 LeetCode 80. 删除排序数组中的重复项 II

给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度。

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

示例 1:

给定 nums = [1,1,1,2,2,3],

函数应返回新长度 length = 5, 并且原数组的前五个元素被修改为 1, 1, 2, 2, 3 。

你不需要考虑数组中超出新长度后面的元素。

示例 2:

给定 nums = [0,0,1,1,1,1,2,3,3],

函数应返回新长度 length = 7, 并且原数组的前五个元素被修改为 0, 0, 1, 1, 2, 3, 3 。

你不需要考虑数组中超出新长度后面的元素。

说明:

为什么返回数值是整数,但输出的答案是数组呢?

请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。

你可以想象内部操作如下:

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

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

代码:

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int n=nums.size();
        if (n<=2) return n;
        int j=2;
        for (int i = 2; i < n; i++) {
            if(nums[i]!=nums[j-2]){
                nums[j] = nums[i];
                j++;
            }
        }
        return j;
    }
};

2.1 LeetCode 75. 颜色分类

给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

注意:
不能使用代码库中的排序函数来解决这道题。

示例:

输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]

进阶:

  • 一个直观的解决方案是使用计数排序的两趟扫描算法。
  • 首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前数组。
    你能想出一个仅使用常数空间的一趟扫描算法吗?
class Solution {
public:
    void sortColors(vector<int>& nums) {
        int zero = -1;
        int tow = nums.size();
        for (int i = 0; i < tow; ) {
            if(nums[i]==1){
                i++;
            } else if (nums[i]==0){
                zero++;
                swap(nums[i], nums[zero]);
                i++;
            } else{
                __glibcxx_assert(nums[i]==2);
                tow--;
                swap(nums[i], nums[tow]);
            }
        }
    }
};

2.2 LeetCode 88. 合并两个有序数组

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

说明:

  • 初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。
  • 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。

示例:

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

输出: [1,2,2,3,5,6]
class Solution {
public:
    void merge(vector<int> &nums1, int m, vector<int> &nums2, int n) {
        int i = m + n - 1;
        m--;
        n--;
        while (n >= 0 && m >= 0) {
            if(nums1[m]>nums2[n]) {
                nums1[i] = nums1[m];
                m--;
            } else{
                nums1[i] = nums2[n];
                n--;
            }
            i--;
        }
        while (n >= 0) {
            nums1[i] = nums2[n];
            n--;
            i--;
        }
    }
};

2.3 LeetCode 215. 数组中的第K个最大元素

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5

示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4

解法一:划分区域+二分查找

class Solution {
public:
    int findKthLargest(vector<int> &nums, int k) {
        int n = nums.size();
        __glibcxx_assert(k < 0 && k < n);
        return findK(nums, 0, n - 1, n - k + 1);
    }
private:
    //二分查找K
    int findK(vector<int> &nums, int l, int r, int k) {
        int index = partition(nums, l, r);
        int Kth = index - l + 1;
        if (k == Kth) {
            return nums[index];
        } else if (k < Kth) {
            return findK(nums, l, index - 1, k);
        } else {
            return findK(nums, index + 1, r, k - Kth);
        }
    }
    //划分区域
    int partition(vector<int> &nums, int l, int r) {
        int e = nums[l];
        int front = l + 1;  //[l+1,front)
        int rear = r;         //(rear,r]
        while (front <= rear) {
            while (front <= rear && nums[front] <= e)
                front++;
            while (front <= rear && nums[rear] > e)
                rear--;
            if (front < rear)
                swap(nums[front], nums[rear]);
        }
        swap(nums[l], nums[rear]);
        return rear;
    }
};

第2部分 双指针(对撞指针)

  • 对撞指针

3.1 LeetCode 167. 两数之和 II - 输入有序数组

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

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

说明:

  • 返回的下标值(index1 和 index2)不是从零开始的。
  • 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。
    示例:
输入: numbers = [2, 7, 11, 15], target = 9
输出: [1,2]
解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

解法一:双指针法

class Solution {
public:
    vector<int> twoSum(vector<int> &numbers, int target) {
        int low = 0;  //[0, low)
        int high = numbers.size() - 1;//(high, numbers.size() - 1]
        int ans[2] = {-1, -1};
        while (high > low) { //high==low 时指向同一个元素
            int res = numbers[high] + numbers[low];
            if (res == target) {
                return {low + 1, high + 1};
            } else if (res < target) {
                low++;
            } else {
                high--;
            }
        }
        return {-1, -1};
    }
};

3.2 LeetCode 125. 验证回文串

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

**说明:**本题中,我们将空字符串定义为有效的回文串。

示例 1:

输入: "A man, a plan, a canal: Panama"
输出: true

示例 2:

输入: "race a car"
输出: false

解法一:双指针法

class Solution {
public:
    bool isPalindrome(string s) {
        int low = 0;
        int high = s.size() - 1;
        while (low < high) { // 当 low == high 时不用考虑
            while (low < high && !isalnum(s[low]))
                low++;
            while (low < high && !isalnum(s[high]))
                high--;
            //if (low < high && tolower(s[low]) != tolower(s[high])) 亦可以
            if (tolower(s[low]) != tolower(s[high])) 
                return false;
            low++;
            high--;
        }
        return true;
    }
};

3.2 LeetCode 334. 递增的三元子序列

给定一个未排序的数组,判断这个数组中是否存在长度为 3 的递增子序列。

数学表达式如下:

  • 如果存在这样的 i, j, k, 且满足 0 ≤ i < j < k ≤ n-1,

  • 使得 arr[i] < arr[j] < arr[k] ,返回 true ; 否则返回 false 。

    说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1) 。

示例 1:

输入: [1,2,3,4,5]
输出: true

示例 2:

输入: [5,4,3,2,1]
输出: false

解法一:双指针法

class Solution {
public:
    bool increasingTriplet(vector<int> &nums) {
        int n = nums.size();
        if (n < 3) return false;
        int first = INT_MAX;
        int second = INT_MAX;
        for (int i = 0; i < nums.size(); ++i) {
            if (nums[i] <= first) {
                first = nums[i];
            } else if (nums[i] <= second) {
                second = nums[i];
            } else if (nums[i] > second) {
                return true;
            }
        }
        return false;
    }
};

3.3 LeetCode 345. 反转字符串中的元音字母

编写一个函数,以字符串作为输入,反转该字符串中的元音字母。

示例 1:

输入:"hello"
输出:"holle"

示例 2:

输入:"leetcode"
输出:"leotcede"

解法一:对撞指针

class Solution {
public:
    void reverseString(vector<char> &s) {
        int r = s.size() - 1;
        int l = 0;
        while (r > l) {
            swap(s[l], s[r]);
            r--;
            l++;
        }
    }
};

3.4 LeetCode 345. 反转字符串中的元音字母

编写一个函数,以字符串作为输入,反转该字符串中的元音字母。

示例 1:

输入:"hello"
输出:"holle"

示例 2:

输入:"leetcode"
输出:"leotcede"

提示:

  • 元音字母不包含字母 “y” 。

解法一:对撞指针

class Solution {
public:
    unordered_set<char> flag{'a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'};
    string reverseVowels(string s) {
        int r = s.size() - 1;
        int l = 0;
        while (l < r) {
            while (l < r && flag.find(s[l]) == flag.end()) {
                l++;
            }
            while (l < r && flag.find(s[r]) == flag.end()) {
                r--;
            }
            if (l < r){
                swap(s[l], s[r]);
                l++;
                r--;
            }
        }
        return s;
    }
};

3.5 LeetCode 11. 盛最多水的容器

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

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

img

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

示例:

输入:[1,8,6,2,5,4,8,3,7]
输出:49

解法一:对撞指针

class Solution {
public:
    int maxArea(vector<int> &height) {
        int m = 0;
        int l = 0;
        int r = height.size() - 1;
        while (l < r) {
            if (height[l] < height[r]){
                m = max(m, (r - l) * height[l]);
                l++;
            }else{
                m = max(m, (r - l) * height[r]);
                r--;
            }
        }
        return m;
    }
};

第3部分 滑动窗口

4.1 LeetCode 209. 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

示例:

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

进阶:

  • 如果你已经完成了 O(n) 时间复杂度的解法, 请尝试 O(n log n) 时间复杂度的解法。

解法一:滑动窗口

class Solution {
public:
    int minSubArrayLen(int s, vector<int> &nums) {
        int l = 0;
        int r = -1;//滑动窗口[l,r]
        int sum = 0;
        int length = nums.size() + 1;
        
        while (l < nums.size()) {
            if (r + 1 < nums.size() && sum < s) {
                r++;
                sum += nums[r];
            } else {
                sum -= nums[l];
                l++;
            }
            if (sum >= s)
                length = min(length, r - l + 1);
        }
        if (length == nums.size() + 1)
            return 0;
        return length;
    }
};

4.2 LeetCode 3. 无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

解法一:滑动窗口

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int freq[256] = {0};
        int m = -1;
        int l = 0;
        int r = -1;//滑动窗口[l,r]
        while (l < s.length()) {
            if (r + 1 < s.length() && freq[s[r + 1]] == 0) {
                r++;
                freq[s[r]]++;
            } else {
                freq[s[l]]--;
                l++;
            }
            m = max(m, r - l + 1);
        }
        if (m == -1) return 0;
        return m;
    }
};

解法二:滑动窗口

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int freq[256] = {0};
        int m = 0;
        int l = 0;
        int r = -1;//滑动窗口[l,r]
        while (l < s.length()) {
            if (r + 1 < s.length() && freq[s[r + 1]] == 0) {
                r++;
                freq[s[r]]++;
            } else {
                freq[s[l]]--;
                l++;
            }
            m = max(m, r - l + 1);
        }
        return m;
    }
};

解法三:滑动窗口(遍历字符数组)

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if (s.length() == 0)
            return 0;
        int freq[256] = {0};
        int m = -1;
        int l = 0;
        int r = -1;//滑动窗口[l,r]
        for (int i = 0; i < s.length();) {//遍历字符数组
            if (freq[s[i]] == 0) {
                r++;
                freq[s[i]]++;
                i++;
            } else {
                freq[s[l]]--;
                l++;
            }
            m = max(m, r - l + 1);
        }
        return m;
    }
};

4.3 LeetCode 438. 找到字符串中所有字母异位词

给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。

字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。

说明:

  • 字母异位词指字母相同,但排列不同的字符串。
  • 不考虑答案输出的顺序。

示例 1:

输入:
s: "cbaebabacd" p: "abc"

输出:
[0, 6]

解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的字母异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的字母异位词。

示例 2:

输入:
s: "abab" p: "ab"

输出:
[0, 1, 2]

解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的字母异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的字母异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的字母异位词。

解法一:滑动窗口

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int freq[256] = {0};
        for (int i = 0; i < p.length(); ++i) {
            freq[p[i]]++;
        }

        vector<int> res;
        int l = 0;
        int r = -1;
        while (l < s.length()) {
            if (r + 1 < s.length() && freq[s[r + 1]] != 0) {
                r++;
                freq[s[r]]--;
            } else {
                freq[s[l]]++;
                l++;
            }
            if (r - l + 1 == p.size())
                res.push_back(l);
        }
        return res;
    }
};

4.4 LeetCode *76. 最小覆盖子串

给你一个字符串 S、一个字符串 T 。请你设计一种算法,可以在 O(n) 的时间复杂度内,从字符串 S 里面找出:包含 T 所有字符的最小子串。

示例:

输入:S = "ADOBECODEBANC", T = "ABC"
输出:"BANC"

提示:

  • 如果 S 中不存这样的子串,则返回空字符串 “”。
  • 如果 S 中存在这样的子串,我们保证它是唯一的答案。

解法一:滑动窗口

class Solution {
public:
    string minWindow(string s, string t) {
        int winFreq[128] = {0};
        int tFreq[128] = {0};
        for (int i = 0; i < t.size(); ++i) {
            tFreq[t[i]]++;
        }

        int ans[2] = {-1, -1};
        int l = 0;
        int r = -1;
        int distance = 0;
        int len = s.size() + 1;

        while (l < s.size()) {
            if (distance == t.size()) {//移动左端点
                if (len > r - l + 1) {
                    ans[0] = l;
                    ans[1] = r;
                    len = r - l + 1;
                }
                if (winFreq[s[l]] <= tFreq[s[l]]) {
                    distance--;
                }
                winFreq[s[l]]--;
                l++;
            } else if (r + 1 < s.size()) {//移动右端点
                r++;
                if (winFreq[s[r]] < tFreq[s[r]]) {
                    distance++;
                }
                winFreq[s[r]]++;
            } 
            //distance < t.size() && r == s.size() - 1 滑动窗口中不可能符合条件
            if (distance < t.size() && r == s.size() - 1) {
                break;
            }
        }
        if (len == s.size() + 1)
            return "";
        return s.substr(ans[0], ans[1] - ans[0] + 1);
    }
};

解法二:滑动窗口

class Solution {
public:
    string minWindow(string s, string t) {
        int winFreq[128] = {0};
        int tFreq[128] = {0};
        for (int i = 0; i < t.size(); ++i) {
            tFreq[t[i]]++;
        }

        int ans[2] = {0, -1};//滑动窗口区间
        int l = 0;
        int r = -1;
        int distance = 0;
        int len = s.size() + 1;

        while (l < s.size()) {
            if (distance == t.size()) {//移动左端点
                if (len > r - l + 1) {
                    ans[0] = l;
                    ans[1] = r;
                    len = r - l + 1;
                }
                if (winFreq[s[l]] <= tFreq[s[l]]) {
                    distance--;
                }
                winFreq[s[l]]--;
                l++;
            } else if (r + 1 < s.size()) {//移动右端点
                r++;
                if (winFreq[s[r]] < tFreq[s[r]]) {
                    distance++;
                }
                winFreq[s[r]]++;
            } else //已不能满足条件
                break;
        }
        return s.substr(ans[0], ans[1] - ans[0] + 1);
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值