当前位置: 首页 > news >正文

单序列双指针---初阶篇

目录

相向双指针

344. 反转字符串

125. 验证回文串

1750. 删除字符串两端相同字符后的最短长度

2105. 给植物浇水 II

977. 有序数组的平方

658. 找到 K 个最接近的元素

1471. 数组中的 k 个最强值

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

633. 平方数之和

2824. 统计和小于目标的下标对数目

2563. 统计公平数对的数目

LCP 28. 采购方案

15. 三数之和

16. 最接近的三数之和

18. 四数之和

611. 有效三角形的个数

1577. 数的平方等于两数乘积的方法数

923. 三数之和的多种可能

948. 令牌放置

11. 盛最多水的容器

42. 接雨水

1616. 分割两个字符串得到回文串

同向双指针

611. 有效三角形的个数

背向双指针

1793. 好子数组的最大分数

原地修改

27. 移除元素

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

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

283. 移动零

905. 按奇偶排序数组

922. 按奇偶排序数组 II

3467. 将数组按照奇偶性转化

2460. 对数组执行操作

1089. 复写零

总结


本文对双指针算法在面试中的常见应用进行了详细分类和解析,帮助读者掌握双指针的解题技巧和底层逻辑。双指针可以分为相向双指针、同向双指针和背向双指针,分别适用于不同的问题场景,一下将一一列举。通过本文的学习,帮助读者可以更好地理解双指针的核心思想,并灵活运用于实际面试中。PS:本篇博客中的所有题目均来自于灵茶山艾府 - 力扣(LeetCode)分享的题单。

相向双指针

与滑动窗口相反,滑动窗口是同向双指针,left和right都向右或向左移动;相向双指针指的是两个指针都向中间进行移动。下面借助题目进行理解和剖析。

344. 反转字符串

题解:经典的现象双指针问题,使用前后指针进行字符串的交换即可。

125. 验证回文串

题解:依旧是使用相向双指针,但是要注意跳过非字母数字字符,还要注意前后字符进行比较的时候是不区分大小写的。

class Solution {
public:bool isPalindrome(string s) {//依旧是使用同向双指针来进行实现int left=0,right=s.size()-1;while(left<right){while(right>left&&(s[right]<'a'||s[right]>'z')&&(s[right]<'A'||s[right]>'Z')&&(s[right]<'0'||s[right]>'9')) right--;while(right>left&&(s[left]<'a'||s[left]>'z')&&(s[left]<'A'||s[left]>'Z')&&(s[left]<'0'||s[left]>'9')) left++;if(tolower(s[left])!=tolower(s[right])) return false;left++,right--;}return true;}
};

1750. 删除字符串两端相同字符后的最短长度

 题解:如果左右两边字符相同进行循环删除接口,当左右两边字符不同是停止,返回字符串长度。

class Solution {
public:int minimumLength(string s) {//使用指针找到前后字符不同的位置后停止,再通过right和left来确定长度int left=0,right=s.size()-1;while(left<right){if(s[left]!=s[right]) break;   //左右两边字符不同break,进行返回char same=s[left];//一下循环条件应该更改为left<=right解决出现s执行没有字符的情况while(left<=right&&same==s[right]) right--;  //出右边相同字符while(left<=right&&same==s[left]) left++;    //出左边相同字符}return right-left+1;}
};

2105. 给植物浇水 II

题解:让左右两边同时进行浇水,当水不足的时候补水;注意:相遇位置谁来浇水。 

class Solution {
public:int minimumRefill(vector<int>& plants, int capacityA, int capacityB) {//依旧是使用相向双指针进行实现int n=plants.size();int left=0,right=n-1;int ret=0;int ahave=capacityA,bhave=capacityB;while(left<right){if(ahave<plants[left]) //A浇水{ahave=capacityA;ret++;}ahave-=plants[left++];if(bhave<plants[right]) //B浇水{bhave=capacityB;ret++;}bhave-=plants[right--];}if(n%2==1&&max(ahave,bhave)<plants[left]) ret++;  //对于奇数个植物需要对相交位置进行判断return ret; }
};

977. 有序数组的平方

题解:对负数和整数进行拆分,以cur1为分界线,则[0,cur1]内的平方是呈现递减的趋势,[cur1+1,n-1]内的平方是呈现递增的趋势。就转化为了合并两个有序数组。

class Solution {
public:vector<int> sortedSquares(vector<int>& nums) {int n=nums.size();int cur1=0;while(cur1<n&&nums[cur1]<0) cur1++;cur1--;  //cur1向前走   从[0,cur1]的平方是降序的int cur2=cur1+1;  //cur2向后走  从[cur2,n-1]的平方是升序的vector<int> ret(n);int k=0;while(cur1>=0&&cur2<n){if(abs(nums[cur1])<abs(nums[cur2])) ret[k++]=nums[cur1]*nums[cur1--];else ret[k++]=nums[cur2]*nums[cur2++];}while(cur1>=0) ret[k++]=nums[cur1]*nums[cur1--];  //判断cur1是否走完了while(cur2<n) ret[k++]=nums[cur2]*nums[cur2++];return ret;}
};

658. 找到 K 个最接近的元素

题解:先找到最接近x的位置,然后再从该位置分别向前,向后取元素。最终确定区间的位置。

class Solution {
public:vector<int> findClosestElements(vector<int>& arr, int k, int x) {//先找到数组中最接近x的位置int n=arr.size();int pos=0;int near=INT_MAX;  //用pos位置来记录最接近x的位置for(int i=0;i<n;i++) {if(near>abs(arr[i]-x)){near=abs(arr[i]-x);pos=i;}}//此时的pos位置就是最接近x的位置int cur1=pos,cur2=pos+1;  //将cur1向前走,cur2向后走,进行一次判断去哪一边的元素while(k&&cur1>=0&&cur2<n){int left=abs(arr[cur1]-x);int right=abs(arr[cur2]-x);if(left>right) cur2++; //取右边的else cur1--;          //取左边的k--;}while(k&&cur1>=0) cur1--,k--;   //防止k还没有完while(k&&cur2<n) cur2++,k--;vector<int> ret(arr.begin()+cur1+1,arr.begin()+cur2);return ret;}
};

1471. 数组中的 k 个最强值

题解:先对数组进行排序找到中间值。因为数组是排序好的,所以左右两边的值是距离中间值最远的,也就是最有可能成为最强值的数,再对左右进行比较确定最强值。

class Solution {
public:vector<int> getStrongest(vector<int>& arr, int k) {int n=arr.size();sort(arr.begin(),arr.end());   //先进行排序找中间值int m=arr[(n-1)/2];//左右两边一定比中间强,所以控制[left,right]区间,从左右两边找最强值vector<int> ret;int left=0,right=n-1;while(k&&left<=right){int lnum=abs(arr[left]-m);int rnum=abs(arr[right]-m);if(lnum>rnum)   //左边大,入左边{ret.push_back(arr[left]);left++;}else   //右边大,入右边{ret.push_back(arr[right]);right--;}k--;}return ret;}
};

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

题解:标准的同向双指针的题目,通过左右两边的最大值和最小值来进行缩小和扩大范围直到找到合适的下标组合。

class Solution {
public:vector<int> twoSum(vector<int>& numbers, int target) {//使用相向双指针来实现,当左右两边之和小的时候就让left++//当左右两数之和大的时候让right--//相等的时候就返回int left=0,right=numbers.size()-1;while(left<right){if(numbers[left]+numbers[right]==target) return {left+1,right+1};  //注意题目中下标是从1开始的else if(numbers[left]+numbers[right]>target) right--;else left++;}return {};}
};

633. 平方数之和

题解:b一定是小于等于sqrt(c)的,所以可以直接确定左右区间使用相向双指针来找合适的a和b即可。

class Solution {
public:bool judgeSquareSum(int c) {int left=0,right=sqrt(c);  //right一定是小于等于c的算数平方根的//所以确定左右边界,通过左右两边的平方和确定区间的移动while(left<=right){long long the=left*left;  long long other=right*right;if(the+other==c) return true;else if(the+other>c) right--;else left++;}return false;}
};

2824. 统计和小于目标的下标对数目

方法一:对数组进行排序,right从后向前,依次找nums[right]组合满足条件的数目,将这些数进行相加即可;满足nums[right]+nums[left]>=target的最小left就是nums[right]可以组合的个数。

class Solution {
public:int countPairs(vector<int>& nums, int target) {sort(nums.begin(),nums.end());int ret=0,n=nums.size();for(int i=n-1;i>0;i--){//使用islower_bound来进行临界条件的查找int r=lower_bound(nums.begin(),nums.begin()+i,target-nums[i])-nums.begin();if(r!=n) ret+=r;}return ret;}
};

方法二:将数组进行排序后,使用相向双指针进行统计;当nums[left]+nums[right]<target的时候nums[left]就可以与[left+1,right]区间的所有数进行配对,ret+=right-left,当前left就完成了对所有数的匹配,left++;当nums[left]+nums[right]>=target时,nums[right]就不能与[left,right]的所有数进行匹配,当前的right就完成了对所有数的匹配,right--。

class Solution {
public:int countPairs(vector<int>& nums, int target) {sort(nums.begin(),nums.end());int left=0,right=nums.size()-1;int ret=0;while(left<right){if(nums[left]+nums[right]<target){ret+=right-left;left++;}else right--;}return ret;}
};

2563. 统计公平数对的数目

题解:与上一题的方法二相似也是使用有序的性质将数对的选择进行剪枝;使用相向双指针进行,当nums[left]+nums[right]>upper时说明此时的right没有与之匹配的left了,将right--;当nums[left]+nums[right]<lower时说明此时的left没有与之匹配的right了,将left++;当在有效区间以内的时候,可以固定right求left满足的个数,也可以固定left求right满足条件的个数。

class Solution {
public:long long countFairPairs(vector<int>& nums, int lower, int upper) {int n=nums.size();sort(nums.begin(),nums.end());  //先进行排序,此时的left和right有序方便对不需要组合进行剪枝int left=0,right=n-1;long long ans=0;while(left<right){if(nums[left]+nums[right]>upper) right--;  //当left+right对应的值大于upper时right就没有匹配的left了else if(nums[left]+nums[right]<lower) left++;  //当left+right对应的值小于lower时left就没有匹配的right了else{//此时的nums[left]+nums[right]是满足题意的,所以可以固定right,将找第一个left不满足条件的位置int end=upper_bound(nums.begin()+left,nums.begin()+right,upper-nums[right])-nums.begin()-left;ans+=end;right--;}}return ans;}
};

LCP 28. 采购方案

题解:与两题一样,还是通过有序的数组对进行剪枝。

class Solution {
public:int purchasePlans(vector<int>& nums, int target) {int n=nums.size();sort(nums.begin(),nums.end());  //先进行排序int left=0,right=n-1;int ret=0;while(left<right){if(nums[left]+nums[right]>target) right--;  //此时right的值不能与[left,right-1]任意一个值进行配对else {ret=(ret+right-left)%1000000007;left++;}}return ret;}
};

15. 三数之和

题解:将三数求和------->两数求和,枚举数组的每一个位置找另外两个数即可。找另外两个数依旧是使用相向双指针进行。

class Solution {
public:vector<vector<int>> threeSum(vector<int>& nums) {int n=nums.size();sort(nums.begin(),nums.end());  //进行排序vector<vector<int>> ret;if(nums[0]>0||nums[n-1]<0) return ret;  //当最大值<0以及最小值>0不可能存在满足的数组for(int i=0;i<n-2;i++){if(i>0&&nums[i]==nums[i-1]) continue;    //当前数与上一个就不需要对当前数进行处理,//否则三元组会重复if(nums[i]+nums[i+1]+nums[i+2]>0) break;   //当最小的三个数之和>0没有三元组了if(nums[i]+nums[n-1]+nums[n-2]<0) continue;   //当最小的数与最大的两个数相加<0,当前的i与任何数都不能进行匹配int left=i+1,right=n-1;   //进行两数之和while(left<right){if(nums[left]+nums[right]+nums[i]>0) right--;       else if(nums[left]+nums[right]+nums[i]<0) left++;else {ret.push_back({nums[left],nums[right],nums[i]});left++;while(left<right&&nums[left]==nums[left-1]) left++;  //跳过重复的数据right--;while(left<right&&nums[right]==nums[right+1]) right--;  }}}return ret;}
};

16. 最接近的三数之和

题解:此题与上一题一样,依旧是枚举每一个元素进行三数之和求最接近的位置即可。

class Solution {
public:int threeSumClosest(vector<int>& nums, int target) {//与三数之和类似,还是枚举每一个位置,用同向双指针进行查找最接近的位置int n=nums.size();sort(nums.begin(),nums.end());long long ret=INT_MAX;for(int i=0;i<n-2;i++){//进行同向双指针让和靠近targetint left=i+1,right=n-1;while(left<right){int differ=nums[i]+nums[left]+nums[right];   //求此时的三数之和if(abs(differ-target)<abs(ret-target)) ret=differ;   //判断时候需要进行更新答案if(nums[i]+nums[left]+nums[right]>target) right--;   //此时三数>target,让right--使其靠近targetelse if(nums[i]+nums[left]+nums[right]<target) left++;      //此时三数<target,让left++使其靠近targetelse return target;   //相等就是最接近的位置,直接进行返回}}return ret;}
};

18. 四数之和

题解:与三数求和类似,将四数求和----->三数求和----->两数求和。

class Solution {
public:vector<vector<int>> fourSum(vector<int>& nums, int target) {//将四数之和----->三数之和------>两数之和int n=nums.size();sort(nums.begin(),nums.end());vector<vector<int>> ret;for(int i=0;i<n-3;i++){if(i&&nums[i]==nums[i-1]) continue;  //防止相同数据进行重复插入for(int j=i+1;j<n;j++){if(j!=i+1&&nums[j]==nums[j-1]) continue;   //防止相同数据进行重复插入int left=j+1,right=n-1;while(left<right){//此处的四个数进行相加可能越界,将int强转为long long防止越界if((long long)nums[i]+nums[j]+nums[left]+nums[right]>target) right--;else if((long long)nums[i]+nums[j]+nums[left]+nums[right]<target) left++;else {ret.push_back({nums[i],nums[j],nums[left],nums[right]});left++;while(left<right&&nums[left]==nums[left-1]) left++;right--;while(left<right&&nums[right]==nums[right+1]) right--;}}}}return ret;}
};

611. 有效三角形的个数

题解:与三数求和类似,此题可以通过先确定一边(最大值或最小值),再通过同向双指针找能够组成三角形的组合即可。当nums[min]+nums[mid]>nums[max]时就一定能够组成三角形。

class Solution {
public:int triangleNumber(vector<int>& nums) {//类似与三数求和,通过固定左右一边,再通过同向双指针找合适的位置int n=nums.size(),ret=0;sort(nums.begin(),nums.end());for(int i=n-1;i>=0;i--)   //固定右边,找[0,i-1]中合适的位置{int left=0,right=i-1;while(left<right){if(nums[right]+nums[left]<=nums[i]) left++;else         //此时的nums[left],nums[right],nums[i]是满足条件的{           //区间[left,right-1]与nums[right],num[i]都可以组成三角型ret+=right-left;  right--;}}}return ret;}
};

1577. 数的平方等于两数乘积的方法数

题解:类似于两数求和,分别遍历nums1和nums2,在另一个数组中使用同向求和来找合适的位置。

class Solution {int ret;void twosum(vector<int>& nums,long long target){int n=nums.size();int left=0,right=n-1;while(left<right){if((long long)nums[left]*nums[right]>target) right--;else if((long long)nums[left]*nums[right]<target) left++;else {int l=1,tmp=left+1;while(tmp<right&&nums[tmp]==nums[tmp-1]) l++,tmp++;  //计算left有多少个相同的数ret+=l;right--;}}}public:int numTriplets(vector<int>& nums1, vector<int>& nums2) {//依旧是两数之和题型//遍历nums1,将nums[i]^2作为target在nums2中找满足的个数sort(nums1.begin(),nums1.end());sort(nums2.begin(),nums2.end());int n1=nums1.size(),n2=nums2.size();ret=0;for(int i=0;i<n1;i++)twosum(nums2,(long long)nums1[i]*nums1[i]);  //进行两数求和for(int i=0;i<n2;i++)twosum(nums1,(long long)nums2[i]*nums2[i]);return ret;}
};

923. 三数之和的多种可能

题解:此题时三数之和的变形题,依旧采用遍历数组,再通过相向双指针进行统计合适的个数。但是要注意的是此题时允许右重复组合出现的,所以可以先对数组各个元素的个数进行统计。

class Solution {
public:int threeSumMulti(vector<int>& nums, int target) {//三数求和变形题unordered_map<int,int> mm;for(auto e:nums) mm[e]++;  //记录每个数据的个数int n=nums.size();sort(nums.begin(),nums.end());int ret=0;for(int i=0;i<n;i++)  //遍历数组{//进行两数求和if(--mm[nums[i]]==0) mm.erase(mm[nums[i]]);int left=i+1,right=n-1;while(left<right){if(nums[left]+nums[right]+nums[i]>target) right--;else if(nums[left]+nums[right]+nums[i]<target) left++;else{//防止left与right的值相等造成的重复计数if(nums[left]==nums[right]) ret=(ret+(mm[nums[right]]-1)*mm[nums[right]]/2)%1000000007;  else ret=(ret+mm[nums[right]]*mm[nums[left]])%1000000007;right--,left++;while(left<right&&nums[left]==nums[left-1]) left++;   //取出重复元素while(left<right&&nums[right]==nums[right+1]) right--;   //取出重复元素}}}return ret;}
};

948. 令牌放置

题解:此题的关键在于如何将利益最大化,根据题意可以看出用已有得分获得最大能量,再用已有能量买最小令牌获取得分即可实现利益最大化。

class Solution {
public:int bagOfTokensScore(vector<int>& tokens, int power) {//当能量不够时,保证每次都使用1分都获取最大的能量//当能量充足的时候,使用能量换取最小的令牌来获得1分,这样就可以使得利益最大化int n=tokens.size();sort(tokens.begin(),tokens.end());  //先进行排序int left=0,right=n-1;int ret=0;while(left<right){if(power<tokens[left])  //能量不够,用得分获得最多能量{if(ret==0) return 0;ret--;power+=tokens[right--];}power-=tokens[left++]; //用最小能量获取得分ret++;}if(left==right&&power>=tokens[left]) ret++;  //判断相等位置是否还可以获得得分return ret;}
};

11. 盛最多水的容器

题解:经典的最大蓄水池问题,采用同向双指针通过每次循环确定一边的最大值即可。

class Solution {
public:int maxArea(vector<int>& height) {//通过左右两边双指针可以直接确定一个挡板可以存储的最多水量//eg:示例1,[0,n-1]此时的0比nums[n-1]小,所以选取0作为一个挡板可以存储的最多水量是[0,n-1]//此时0的最大储水量已经确定了,让0--->1继续向后找;此时nums[n-1]比nums[1]小,//所以以n-1作为一个挡板最大储水量是[1,n-1]此时n-1位置已经确定了,可以让n-1--->n-2//通过同向双指针就可以实现找到最大容量的效果int left=0,right=height.size()-1;int ret=0;while(left<right){if(height[left]>height[right]) {ret=max(ret,height[right]*(right-left));right--;}else {ret=max(ret,height[left]*(right-left));left++;}}return ret;}
};

42. 接雨水

解答一:同向双指针,与“盛最大水的容器”类似,此题依旧是让柱子矮的一边进行移动,但是此时每一次循环确定的是一个位置可以存储的水量,为了获取该位置的水量还需要分别存储左右两边的最长柱子。

class Solution {
public:int trap(vector<int>& height) {//此题可以使用双指针进行实现,依旧移动柱子矮的一边,但是在每一次只是将一列进行注水//并且需要存储左右两边最长的柱子int left=0,right=height.size()-1;int left_max=0,right_max=0;int ret=0;while(left<right){if(height[left]<height[right]){left_max=max(left_max,height[left]);ret+=left_max-height[left++];}else {right_max=max(right_max,height[right]);ret+=right_max-height[right--];}}return ret;}
};

解法二:使用前缀和进行实现;假设右边柱子无穷高,从左向右来确定每个位置可以存储的最大水量;再假设左边柱子无穷高,从右向左来确定每个位置可以存储的最大水量;再取每一个位置的最小值即可得出该位置的真实存水量。

class Solution {
public:int trap(vector<int>& height) {int n=height.size();vector<int> left_area(n);vector<int> right_area(n);int left_max=0,right_max=0;for(int i=0;i<n;i++)   //求从左向右的储水量{left_max=max(left_max,height[i]);left_area[i]=left_max-height[i];}for(int i=n-1;i>=0;i--)   //求从右向左的储水量{right_max=max(right_max,height[i]);right_area[i]=right_max-height[i];}int ret=0;for(int i=0;i<n;i++)  //取两个储水量的较小值即可ret+=min(right_area[i],left_area[i]);return ret;}
};

1616. 分割两个字符串得到回文串

题解:使用同向双指针找到左右两边第一个不对称的位置,以该位置作为基点判断能否形成回文字符串即可。

class Solution {
public:bool same(string& s)  //判断是否是回文字符串{int left=0,right=s.size()-1;while(left<right)if(s[left++]!=s[right--]) return false; return true;}bool checkP(string prev,string next){//通过同向双指针找第一个不相同的位置,以该位置作为基点将左右两边进行拼接,判断拼接后是否形成回文字符串int n=prev.size();int left=0,right=n-1;while(left<right){if(prev[left]!=next[right]) {//[0,left)和[left,n)string tmp1=prev.substr(0,left);tmp1+=next.substr(left,n-left);//[0,right]和(right,n)string tmp2=prev.substr(0,right+1);tmp2+=next.substr(right+1,n-right-1);return same(tmp1)||same(tmp2);}left++,right--;}return true;}bool checkPalindromeFormation(string a, string b) {   return checkP(a,b)||checkP(b,a);}
};

同向双指针

与相向双指针相反,两个指针都向左或者都向右。

611. 有效三角形的个数

题解:关于该题前面在实现的时候使用了:固定最大边+相向双指针进行实现,此处可以使用固定最小边+同向双指针进行实现。

class Solution {
public:int triangleNumber(vector<int>& nums) {//此题可以采用固定最小边a,求另外两条边b,c;需要满足c-b<a//所以b和c之间的距离不能太大,所以可以使用同向双指针int n=nums.size(),ret=0;sort(nums.begin(),nums.end());for(int i=0;i<n-2;i++){int a=nums[i];if(a==0) continue;   //对于长度为0的边不能参与计数//进行同向双指针int count=0,left=i+1;for(int right=i+2;right<n;right++){while(left<right&&nums[right]-nums[left]>=a) left++;count+=right-left;}ret+=count;}return ret;}
};

此处同向双指针与相向双指针类似就不过多举例了。

背向双指针

两个指针从数组中的同一个位置出发,一个向左,另一个向右,背向移动。

1793. 好子数组的最大分数

题解:从k位置使用两个指针分别向左右两边进行扩展;在扩展的时候每次向外扩1,所以要考虑是向左还是向右进行扩展,此处为了保证区间中的最小值尽可能的大,选取左右两边的较大值进行扩展。

class Solution {
public:int maximumScore(vector<int>& nums, int k) {//使用双指针让cur1和cur2分别从k位置向左,向右走//向左右两边扩展的时候尽量选择较大的值,来保证min的结果不会太小int n=nums.size();int cur1=k-1,cur2=k+1;int ret=nums[k],Min=nums[k];while(cur1>=0&&cur2<n){if(nums[cur1]>nums[cur2])  //当cur1的值大于cur2的时候向cur1那边扩{Min=min(Min,nums[cur1]);ret=max(ret,Min*(cur2-cur1));cur1--;}else    //当cur2的值大于cur1的时候向cur2那边扩{Min=min(Min,nums[cur2]);ret=max(ret,Min*(cur2-cur1));cur2++;}}while(cur1>=0)  //解决有一边还没有扩完的情况{Min=min(Min,nums[cur1]);ret=max(ret,Min*(cur2-cur1));cur1--;}while(cur2<n){Min=min(Min,nums[cur2]);ret=max(ret,Min*(cur2-cur1));cur2++;}return ret;}
};

原地修改

原地修改类题型:对数组进行修改使得修改后的数组满足题意;原地修改的方法不固定可能会使用相向双指针,同向双指针也可能会使用背向双指针。

27. 移除元素

题解:可以使用同向双指针来实现,使用prev,cur来记录位置,cur在前面走,当nums[cur]!=val时将cur的值赋给prev,否则让cur++即可。

class Solution {
public:int removeElement(vector<int>& nums, int val) {int n=nums.size();int prev=0,cur=0;while(cur<n){if(nums[cur]!=val)nums[prev++]=nums[cur];cur++;}return prev;}
};

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

题解:使用同向双指针prev,cur解决,cur在前面走,当cur对应的位置满足条件就将cur的元素赋值给prev即可;使用map记录cur前已经出现过的数字。

class Solution {
public:int removeDuplicates(vector<int>& nums) {//使用双指针prev,cur,cur向前走当cur位置的元素满足条件时将cur的元素赋值给prev即可//使用map来记录cur前面已经存在的元素unordered_map<int ,int> mm;int prev=0,n=nums.size();for(int cur=0;cur<n;cur++){if(mm.count(nums[cur])==0) {mm[nums[cur]]++;nums[prev++]=nums[cur];}}return prev;}
};

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

题解:与上一题一样,只需要将cur赋值给prev的条件进行修改即可。

class Solution {
public:int removeDuplicates(vector<int>& nums) {//使用双指针prev,cur,cur向前走当cur位置的元素满足条件时将cur的元素赋值给prev即可//使用map来记录cur前面已经存在的元素unordered_map<int ,int> mm;int prev=0,n=nums.size();for(int cur=0;cur<n;cur++){if(mm[nums[cur]]<2) {mm[nums[cur]]++;nums[prev++]=nums[cur];}}return prev;}
};

283. 移动零

题解:将数组从的0移动到后面----->将数组中的非零移动到前面即可。

class Solution {
public:void moveZeroes(vector<int>& nums) {//将0移动到末尾------->将非零移动到数组前面int prev=0,n=nums.size();for(int cur=0;cur<n;cur++){if(nums[cur]!=0) nums[prev++]=nums[cur];}//此时非0全部移动到前面了//将prev后面的元素全部置为0即可while(prev<n) nums[prev++]=0;}
};

905. 按奇偶排序数组

题解:将偶数放到数组前面,将奇数放到数组后面;可以使用相向双指针left,right;让left向右找奇数,让right向左找偶数,找到后将left和right进行交换即可。

class Solution {
public:vector<int> sortArrayByParity(vector<int>& nums) {//将偶数放在前面,将奇数放在后面//使用相向双指针进行实现,从让left向右走找奇数;让right向左走找偶数int left=0,right=nums.size()-1;while(left<right){while(left<right&&nums[left]%2==0) left++;  //找奇数 while(left<right&&nums[right]%2==1) right--;  //找偶数swap(nums[left],nums[right]);  //将奇偶进行交换}return nums;}
};

922. 按奇偶排序数组 II

题解:与上一题类似;根据题目可以分析出数组元素个数是偶数个,并且奇数位放奇数,偶数位放偶数即可。所以依旧是使用同向双指针left,right,但是left和right每次移动两步。

class Solution {
public:vector<int> sortArrayByParityII(vector<int>& nums) {//将偶数放在前面,将奇数放在后面//使用相向双指针进行实现,从让left向右走找奇数;让right向左走找偶数int n=nums.size();int left=0,right=n-1;while(left<n&&right>0){while(left<n&&nums[left]%2==0) left+=2;  //找奇数 while(right>0&&nums[right]%2==1) right-=2;  //找偶数if(left<n&&right>0)swap(nums[left],nums[right]);  //将奇偶进行交换}return nums;}
};

3467. 将数组按照奇偶性转化

题解:先遍历数组将数组中的奇数置为1,将数组中的偶数置为0;再将数组中的0放到数组前面即可。

class Solution {
public:vector<int> transformArray(vector<int>& nums) {//将数组中的奇数-->1,偶数---->0;再将数组中的0放到数组前面for(auto& e:nums) e=e%2==0?0:1;int prev=0,n=nums.size();for(int cur=0;cur<n;cur++)if(nums[cur]==0) nums[prev++]=nums[cur];while(prev<n) nums[prev++]=1;return nums;}
};  

2460. 对数组执行操作

题解:模拟+同向双指针;

class Solution {
public:vector<int> applyOperations(vector<int>& nums) {int n=nums.size();for(int i=0;i<n-1;i++){if(nums[i]==nums[i+1]){nums[i]*=2;nums[i+1]=0;}}//将非0放到数组前面int prev=0;for(int cur=0;cur<n;cur++){if(nums[cur]!=0) nums[prev++]=nums[cur];}while(prev<n) nums[prev++]=0;return nums;}
};

1089. 复写零

题解:模拟+同向双指针;先模拟规则找到最后一个移动的元素,再从后往前进行复写。

class Solution {
public:void duplicateZeros(vector<int>& nums) {//先通过模拟找到返回数组中的最后一位int n=nums.size();int prev=0,cur=0;while(cur<n){if(nums[prev]==0) cur++;cur++,prev++;}//此时prev-1就是输出数组的最后一位//从prev开始向前移动prev-=1;//注意:有一种特殊情况,当最后一位是0的时候进行向后移只剩一个数没有覆盖,所以只有一个0,没有复写if(cur==n+1) nums[n-1]=0,cur=n-2,prev-=1;  //进行特殊处理,将末尾没有复写的0直接加到结尾即可else cur=n-1;for(;prev>=0;prev--){nums[cur--]=nums[prev];if(nums[prev]==0) nums[cur--]=0; //进行复写}}
};

总结

关于双指针的题目关键在于如何理解题目,两个指针在何时才能向前或向后移动;滑动窗口其实也是双指针的以内,其也属于同向双指针。题目讲解到此就结束了,感谢阅读,让我们在下一篇算法中再见。。

相关文章:

单序列双指针---初阶篇

目录 相向双指针 344. 反转字符串 125. 验证回文串 1750. 删除字符串两端相同字符后的最短长度 2105. 给植物浇水 II 977. 有序数组的平方 658. 找到 K 个最接近的元素 1471. 数组中的 k 个最强值 167. 两数之和 II - 输入有序数组 633. 平方数之和 2824. 统计和小于…...

K8s CoreDNS 核心知识点总结

文章目录 一、章节介绍背景与主旨核心知识点及面试频率 二、知识点详解1. CoreDNS 概述2. 工作原理&#xff08;高频考点&#xff09;服务发现流程 3. 配置与插件系统&#xff08;高频考点&#xff09;核心配置文件&#xff1a;Corefile常用插件 4. Pod DNS策略&#xff08;中频…...

Java视频流RTMP/RTSP协议解析与实战代码

在Java中实现视频直播的输入流处理&#xff0c;通常需要结合网络编程、多媒体处理库以及流媒体协议&#xff08;如RTMP、HLS、RTSP等&#xff09;。以下是实现视频直播输入流的关键步骤和技术要点&#xff1a; 1. 视频直播输入流的核心组件 网络输入流&#xff1a;通过Socket或…...

卓力达电铸镍网:精密制造与跨领域应用的创新典范

目录 引言 一、电铸镍网的技术原理与核心特性 二、电铸镍网的跨领域应用 三、南通卓力达电铸镍网的核心优势 四、未来技术展望 引言 电铸镍网作为一种兼具高精度与高性能的金属网状材料&#xff0c;通过电化学沉积工艺实现复杂结构的精密成型&#xff0c;已成为航空航天、电…...

label-studio功能常用英文翻译

Projects 项目 Settings 设置 Labeling Interface 标注界面 1、Computer Vision 计算机视觉 Semantic Segmentation with Polygons 多边形语义分割 Semantic Segmentation with Masks 掩码语义分割 Object Detection with Bounding Boxes 边界框目标检测 Keypoint Label…...

2025年PMP 学习十六 第11章 项目风险管理 (总章)

2025年PMP 学习十六 第11章 项目风险管理 &#xff08;总章&#xff09; 第11章 项目风险管理 序号过程过程组1规划风险管理规划2识别风险规划3实施定性风险分析规划4实施定量风险分析规划5规划风险应对执行6实施风险应对执行7监控风险监控 目标: 提高项目中积极事件的概率和…...

Jenkins 执行器(Executor)如何调整限制?

目录 现象原因解决 现象 Jenkins 构建时&#xff0c;提示如下&#xff1a; 此刻的心情正如上图中的小老头&#xff0c;火冒三丈&#xff0c;但是不要急&#xff0c;因为每一次错误&#xff0c;都是系统中某个环节在说‘我撑不住了’。 原因 其实是上图的提示表示 Jenkins 当…...

Jenkins 安装与配置指南

Jenkins 安装与配置指南&#xff08;MD 示例&#xff09; markdown Jenkins 安装与配置指南 ## 一、环境准备 1. **系统要求** - 操作系统&#xff1a;Linux/macOS/Windows - Java 版本&#xff1a;JDK 8 或更高&#xff08;建议 JDK 11&#xff09;2. **安装方式** - **L…...

使用unsloth对Qwen3在本地进行微调

Fine-tune Qwen3(100% locally) 使用unsloth进行微调,使用huggingface在本地运行model。 load model from unsloth import FastLanguageModel import torchMODEL = "unsloth/Qwen3-14B" model,tokenizer = FastLanguageModel.from_pretrained(model_name=MODE…...

GpuGeek 实操指南:So-VITS-SVC 语音合成与 Stable Diffusion 文生图双模型搭建,融合即梦 AI 的深度实践

GpuGeek 实操指南&#xff1a;So-VITS-SVC 语音合成与 Stable Diffusion 文生图双模型搭建&#xff0c;融合即梦 AI 的深度实践 前言 本文将详细讲解 So-VITS-SVC 语音合成与 Stable Diffusion 文生图的搭建方法&#xff0c;以及二者与即梦 AI 融合的实践技巧&#xff0c;无论你…...

CSS- 3.1 盒子模型-块级元素、行内元素、行内块级元素和display属性

本系列可作为前端学习系列的笔记&#xff0c;代码的运行环境是在HBuilder中&#xff0c;小编会将代码复制下来&#xff0c;大家复制下来就可以练习了&#xff0c;方便大家学习。 HTML系列文章 已经收录在前端专栏&#xff0c;有需要的宝宝们可以点击前端专栏查看&#xff01; 点…...

使用exceljs将excel文件转化为html预览最佳实践(完整源码)

前言 在企业应用中&#xff0c;我们时常会遇到需要上传并展示 Excel 文件的需求&#xff0c;以实现文件内容的在线预览。经过一番探索与尝试&#xff0c;笔者最终借助 exceljs 这一库成功实现了该功能。本文将以 Vue 3 为例&#xff0c;演示如何实现该功能&#xff0c;代码示例…...

7. 进程控制-进程替换

目录 1. 进程替换 1.1 单进程版&#xff1a; 1.2 进程替换的原理 1.3 多进程版-验证各种程序替换接口 2. 进程替换的各种接口 2.1 execl 2.2 execlp 2.3 execv 2.4 execvp 2.5 execle 1. 进程替换 上图为程序替换的接口&#xff0c;之后会详细介绍。 1.1 单进程版&am…...

关于计算机系统和数据原子性的联系

目录 1、计算机架构 1.1、处理器架构 1.2、内存寻址能力 1.3、性能差异 1.4、软件兼容性 1.5、指令集 1.6、开发和维护 2.、基本数据类型 3、原子类型 3.1、基本概念 3.2、基本数据类型的原子性 3.3、原子操作的解释 3.4、不保证原子性 3.5、解决方案 4、原子性…...

Armijo rule

非精线搜索步长规则Armijo规则&Goldstein规则&Wolfe规则_armijo rule-CSDN博客 [原创]用“人话”解释不精确线搜索中的Armijo-Goldstein准则及Wolfe-Powell准则 – 编码无悔 / Intent & Focused...

从数据包到可靠性:UDP/TCP协议的工作原理分析

之前我们已经使用udp/tcp的相关接口写了一些简单的客户端与服务端代码。也了解了协议是什么&#xff0c;包括自定义协议和知名协议比如http/https和ssh等。现在我们再回到传输层&#xff0c;对udp和tcp这两传输层巨头协议做更深一步的分析。 一.UDP UDP相关内容很简单&#xf…...

Prometheus实战教程:k8s平台-Mysql监控案例

配置文件优化后的 Prometheus 自动发现 MySQL 实例的完整 YAML 文件。该配置包括&#xff1a; MySQL Exporter 部署&#xff1a;使用 ConfigMap 提供 MySQL 连接信息。Prometheus 自动发现&#xff1a;通过 Kubernetes 服务发现自动抓取 MySQL 实例。 1、mysql 配置文件 &…...

执行apt-get update 报错ModuleNotFoundError: No module named ‘apt_pkg‘的解决方案汇总

Ubuntu版本ubuntu18.04 报错内容&#xff1a; //执行apt-get upgrade报错&#xff1a; Traceback :File “/usr/lib/cnf-update-db”, line 8, in <module>from CommandNotFound.db.creator import DbcreatorFile “/usr/lib/python3/dist-packages/CommandNotFound/db…...

QT6 源(101)篇一:阅读与注释 QPlainTextEdit,其继承于QAbstractScrollArea,属性学习与测试

&#xff08;1&#xff09; &#xff08;2&#xff09; &#xff08;3&#xff09;属性学习与测试 &#xff1a; &#xff08;4&#xff09; &#xff08;5&#xff09; 谢谢...

Redis(2):Redis + Lua为什么可以实现原子性

Redis 作为一款高性能的键值对存储数据库&#xff0c;与 Lua 脚本相结合&#xff0c;为实现原子性操作提供了强大的解决方案&#xff0c;本文将深入探讨 Redis Lua 实现原子性的相关知识 原子性概念的厘清 在探讨 Redis Lua 的原子性之前&#xff0c;我们需要明确原子性的概念…...

ios打包ipa获取证书和打包创建经验分享

在云打包或本地打包ios应用&#xff0c;打包成ipa格式的app文件的过程中&#xff0c;私钥证书和profile文件是必须的。 其实打包的过程并不难&#xff0c;因为像hbuilderx这些打包工具&#xff0c;只要你输入的是正确的证书&#xff0c;打包就肯定会成功。因此&#xff0c;证书…...

Python生成器:高效处理大数据的秘密武器

生成器概述 生成器是 Python 中的一种特殊迭代器&#xff0c;通过普通函数的语法实现&#xff0c;但使用 yield 语句返回数据。生成器自动实现了 __iter__() 和 __next__() 方法&#xff0c;因此可以直接用于迭代。生成器的核心特点是延迟计算&#xff08;lazy evaluation&…...

C++11(2)

文章目录 右值引用和移动语义在传参中的提效list容器push_back & insert右值版本的模拟实现类型分类 (了解即可&#xff09;引用折叠万能引用 完美转发&#xff08;跟引用折叠有关&#xff09; 简介&#xff1a;这篇文章是继续介绍C11的一些新语法知识点&#xff0c;也是对…...

unity terrain 在生成草,树,石头等地形障碍的时候,无法触发碰撞导致人物穿过模型

1.terrain地形的草&#xff0c;石头之类要选择模型预制体 2.在人物身上挂碰撞器和刚体&#xff0c;或者单挂一个character controller组件也行 3.在预制体上挂碰撞盒就好了&#xff0c;挂载meshcollider会导致碰撞无效...

以项目的方式学QT开发C++(二)——超详细讲解(120000多字详细讲解,涵盖qt大量知识)逐步更新!

API 描述 函数原型 参数说明 push_back() 在 list 尾部 添加一个元素 void push_back(const T& value); value &#xff1a;要添 加到尾部的元 素 这个示例演示了如何创建 std::list 容器&#xff0c;并对其进行插入、删除和迭代操作。在实际应用中&am…...

养生:健康生活的极简攻略

在追求高效生活的当下&#xff0c;养生也能化繁为简。通过饮食、运动、睡眠与心态的精准调节&#xff0c;就能轻松为健康续航。 饮食上&#xff0c;遵循 “均衡、节制” 原则。早餐用一杯热豆浆搭配水煮蛋和半个苹果&#xff0c;唤醒肠胃活力&#xff1b;午餐以糙米饭为主食&am…...

C语言-8.数组

8.1数组 8.1.1初试数组 如何写一个程序计算用户输入的数字的平均数? #include<stdio.h> int main() {int digit;//输入要求平均数的数字double sum=0;//记录输入数字的和int count=0;//记录输入数字的个数printf("请输入一组数字,用来求平均数,以-1结束\n&quo…...

代码随想录算法训练营第四十一天

LeetCode题目: 739. 每日温度496. 下一个更大元素 I503. 下一个更大元素 II 其他: 今日总结 往期打卡 739. 每日温度 跳转: 739. 每日温度 学习: 代码随想录公开讲解 问题: 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &…...

c++,windows,多线程编程详细介绍

目录 一、C11 标准库 <thread> 实现多线程编程1. 基本线程创建2. 线程管理3. 线程传参4. 同步机制5. 异步编程 二、Windows API 实现多线程编程1. 基本线程创建2. 线程管理3. 线程传参 三、两种方法的对比 在 Windows 平台上使用 C 进行多线程编程&#xff0c;可以通过 C…...

Python多线程

Python多线程 作为一名Python开发者&#xff0c;你是否遇到过这样的场景&#xff1a;程序需要同时处理多个任务&#xff0c;但单线程执行效率太低&#xff1f;这时候&#xff0c;多线程技术就能派上用场了。本文将带你深入浅出地理解Python多线程&#xff0c;并通过丰富的示例…...

VisionPro斑点寻找工具Blob

斑点寻找工具Blob 斑点概述 斑点分析 探测并且分析图像中的二维形状Blob是先根据用户设定好的灰阶范围对图像进行分割&#xff0c;然后对目标进行查找和分析。斑点报告多种属性&#xff1a; 面积质心周长主轴…….. 应用场景 Blob分析非常适合以下场合的应用&#xff1a; 对…...

【Python】【面试凉经】Fastapi为什么Fast

核心的关键词&#xff1a;ASGI、原生异步、协程、uvloop、异步生态、Pydantic编译时生成校验代码、DI system预计算依赖树 interviewer 00:32:49 FastAPI 它优越于其他一些主流web框架像 django或 flask 的这个点在哪里&#xff1f; 我 00:33:00fastapi 就是说它的 fast 性能高…...

LocalDateTime类型的时间在前端页面不显示或者修改数据时因为LocalDateTime导致无法修改,解决方案

1.数据库中的时间数据&#xff0c;在控制台可以正常返回&#xff0c;在前端无法返回&#xff0c;即显示空白&#xff0c;如下图所示: 2.这种问题一般时由于数据库和我们实体类的名称不一致引起的&#xff0c;我们数据库一般采用_的方式命名&#xff0c;但是在Java中我们一般采用…...

【Linux】gcc从源码编译安装,修改源码,验证修改的源码

前阵子电脑使用的win10&#xff0c;win10过几天就让升级&#xff0c;烦得不行。 然后把操作系统切换到ubuntu24的样子,然后也是让升级&#xff0c;又烦的不行&#xff0c;然后切换到ubuntu server版本&#xff0c;感觉用起来要舒服些了&#xff0c;至少不会天天让升级。 回到标…...

牛客网NC22157:牛牛学数列2

牛客网NC22157:牛牛学数列2 &#x1f4dd; 题目描述 &#x1f50d; 输入输出说明 输入描述&#xff1a; 输入一个整数 N&#xff0c;范围在 0 到 1000 输出描述&#xff1a; 输出一个保留6位小数的浮点数 示例&#xff1a; 输入&#xff1a;2输出&#xff1a;1.500000 …...

智能手表集成测试报告(Integration Test Report)

&#x1f4c4; 智能手表集成测试报告&#xff08;Integration Test Report&#xff09; 项目名称&#xff1a;Aurora Watch S1 测试阶段&#xff1a;系统集成测试 测试周期&#xff1a;2025年xx月xx日 – 2025年xx月xx日 报告编号&#xff1a;AW-S1-ITR-2025-001 版本&#xf…...

1C:ENTERPRISE 8.3 实用开发者指南-示例和标准技术(Session1-Session3)

1C:ENTERPRISE 8.3&#xff08;1课-3课&#xff09; 本博客是全网首个关于1C:Enterprice的中文指南&#xff0c;支持快速吸收使用 1C:Enterprise 8.3 软件开发和调整应用程序的技术 在这篇博客中我会基于实际应用示例&#xff0c;演示各种系统对象的结构、功能和用法。使用内…...

AgenticSeek开源的完全本地的 Manus AI。无需 API,享受一个自主代理,它可以思考、浏览 Web 和编码,只需支付电费。

​一、软件介绍 文末提供程序和源码下载 AgenticSeek开源的完全本地的 Manus AI。无需 API&#xff0c;享受一个自主代理&#xff0c;它可以思考、浏览 Web 和编码&#xff0c;只需支付电费。这款支持语音的 AI 助手是 Manus AI 的 100% 本地替代品 &#xff0c;可自主浏览网页…...

Java类一文分解:JavaBean,工具类,测试类的深度剖析

解锁Java类的神秘面纱&#xff1a;从JavaBean到测试类的深度剖析 前言一、JavaBean 类&#xff1a;数据的守护者&#xff08;一&#xff09;JavaBean 类是什么&#xff08;二&#xff09;JavaBean 类的特征&#xff08;三&#xff09;JavaBean 类的使用场景&#xff08;四&…...

2025认证杯数学建模第二阶段C题:化工厂生产流程的预测和控制,思路+模型+代码

2025认证杯数学建模第二阶段思路模型代码&#xff0c;详细内容见文末名片 一、探秘化工世界&#xff1a;问题背景大揭秘 在 2025 年 “认证杯”数学中国数学建模网络挑战赛第二阶段 C 题中&#xff0c;我们一头扎进了神秘又复杂的化工厂生产流程预测与控制领域。想象一下&…...

day 17 无监督学习之聚类算法

一、聚类流程 1. 利用聚类发现数据模式 无监督算法中的聚类&#xff0c;目的就是将数据点划分成不同的组或 “簇”&#xff0c;使得同一簇内的数据点相似度较高&#xff0c;而不同簇的数据点相似度较低&#xff0c;从而发现数据中隐藏的模式。 2. 对聚类后的类别特征进行可视…...

渗透测试流程-上篇

#作者&#xff1a;允砸儿 #日期&#xff1a;乙巳青蛇年 四月十八 本期就开始进入到网安的内容了笔者会和大家一起开始实操练习。在此之前笔者的老师和我说要知己知彼&#xff0c;胆大心细。笔者也把他的理念传出去&#xff0c;网安的知识比较复杂且使用的工具很多。笔者看过…...

Ubuntu离线安装Minio

MinIO 支持在 Linux 环境下离线安装&#xff0c;非常适合内网或无法联网的服务器环境。下面是详细的 Linux 离线安装 MinIO 服务端 的步骤&#xff1a; ✅ 一、准备工作 1. 创建安装目录&#xff08;可选&#xff09; mkdir -p /opt/minio cd /opt/minio2. 下载 MinIO 可执行…...

2025年山东省数学建模F题思路

2025年山东省数学建模F题思路 一、问题背景 在现代金融市场中&#xff0c;资产价格波动呈现出非线性、高噪声、强跨市场联动性等复杂动态特征。例如&#xff0c;2020年新冠疫情期间&#xff0c;美股数次熔断事件引发全球股市剧烈震荡&#xff1b;而2023年美元加息周期&#x…...

C++核心编程--3 函数提高

函数的一些高级用法。 3.1 函数形参默认值 C中&#xff0c;函数的形参可以有默认值&#xff0c;调用函数时&#xff0c;未进行赋值的形参会使用默认值 void func(int f_var1 10, int f_var2 20); // 声明 ​ void func(int f_var1, int f_var2) // 定义 {std::cout <&l…...

AI Agent开发第67课-彻底消除RAG知识库幻觉(1)-文档分块全技巧

开篇 在上篇《AI Agent开发第66课-彻底消除RAG知识库幻觉-带推理的RAG》放出后,网友们反响很大。有得告诉我:原来还有Rewrite这么一招?早知道这一招很多之前的一些遗留问题都能解决了。不过在上一篇结尾我已经提到了,要真正解决一个AI Agent在响应时产生的幻觉我们用提示语…...

c++多态面试题之(析构函数与虚函数)

有以下问题展开 析构函数要不要定义成虚函数&#xff1f;基类的析构函数要不要定义成虚函数&#xff1f;如果不定义会有什么问题&#xff0c;定义了在什么场景下起作用。 1. 基类析构函数何时必须定义为虚函数&#xff1f; 当且仅当通过基类指针&#xff08;或引用&#xff09;…...

buildroot使用外部编译链编译bluez蓝牙工具

buildroot使用外部编译链编译bluez蓝牙工具 主要参见这个csdn buildroot使用外部编译链编译bluez蓝牙工具_bluez编译-CSDN博客 设置交叉编译工具路径时&#xff0c;设置到bin目录之前 如果menuconfig不能改路径&#xff0c;就去 .config下去改 这样才能编译过...

自定义类型:结构体

1.结构体类型的声明 1.1.1结构的声明 struct tag {member-list; }variable-list; 描述一个学生&#xff1a;只包含了学生的名字、年龄、性别、学号 struct Stu {char name[20];//名字int age;//年龄char sex[5];//性别char id[20];//学号 }; 1.1.2 结构体变量的创建和初始…...

以项目的方式学QT开发C++(一)——超详细讲解(120000多字详细讲解,涵盖qt大量知识)逐步更新!

以项目的方式学QT开发 以项目的方式学QT开发 P1 QT介绍 1.1 QT简介 1.2 QT安装 1.2.1 Windows QT安装 1.2.2 QT Creator 使用基本介绍 P2 C基础 2.1 命名空间 2.1.1 命名空间作用 2.1.2 自定义命名空间 2.2 从C语言快速入门 2.2.1 输入输出 2.2.2 基…...