轮转数组
给你一个数组,将数组中的元素向右轮转 k
个位置,其中 k
是非负数。
解法一:引入新数组存放计算结果,然后重新套回去
关键是公式 ( i + k ) % numsSize
void rotate(int* nums, int numsSize, int k){
int temparray[numsSize];
for(int i=0;i<numsSize;i++){
temparray[(i+k)%numsSize] = nums[i];
}
for(int i=0;i<numsSize;i++){
nums[i] = temparray[i];
}
}
解法二:翻转再翻转
双指针分而治之
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}
void reserve(int *nums,int lo,int hi){
while(lo<hi){
swap(&nums[lo++],&nums[hi--]);
}
}
void rotate(int* nums, int numsSize, int k){
k%=numsSize; //以numsSize为周期,排除大量翻转
reserve(nums,0,numsSize-1);
reserve(nums,0,k-1);
reserve(nums,k,numsSize-1);
}
有序数组的平方
给你一个按 非递减顺序 排序的整数数组 nums
,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
解析:使用双指针对数组每一个数进行平方然后排序。
对首尾两个数字进行平方后的比较,较大者会补充到新数组的最后一位,然后较大者左移/右移一位再进行下一轮比较,由此比较完毕既可以得出答案
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* sortedSquares(int* nums, int numsSize, int* returnSize){
*returnSize = numsSize;
int* ans = (int*)malloc(sizeof(int) * numsSize);
int left = 0,right = numsSize-1,index=numsSize-1;
while(left<=right){
if(nums[left]*nums[left]<nums[right]*nums[right]){
ans[index] = nums[right]*nums[right];
right--;
}else{
ans[index] = nums[left]*nums[left];
left++;
}
index--;
}
return ans;
}
移动零(重点)
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
解析:该题使用新的方式去诠释双指针,两个指针从零点开始指,这样可以保持原数组交换后的顺序仍然是顺序排列。
而且里面的思想非常有趣,左指针作为功能指针,右指针作为计数指针。
可以看到无论如何右指针在出口处是必然会进行加一,保证程序在一步一步的进行下去,而左指针发挥swap两个数字的功能,如果指针同指非零数,左右指针往右移,直到出现零,那就只有右指针移动,这样会出现交换的情况。
void swap(int *a,int *b){
int temp = *a;
*a = *b;
*b = temp;
}
void moveZeroes(int* nums, int numsSize){
int lo = 0,hi = 0;
while(hi<numsSize){
if(nums[hi]){
swap(&nums[lo],&nums[hi]);
lo++;
}
hi++;
}
}
两数之和
解析:引入其他变量进行判断指针是否移动
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* numbers, int numbersSize, int target, int* returnSize){
*returnSize = 2;
int *ans = (int*)malloc(sizeof(int) * 2);
int lo=0,hi=numbersSize-1;
while(lo<hi){
int sum = numbers[lo] + numbers[hi];
if(target==sum){
ans[0] = lo + 1;
ans[1] = hi + 1;
break;
}else if(target > sum){
lo++;
}else if(target < sum){
hi--;
}
}
return ans;
}
反转字符串小专题
解析:直接用最简单直接的办法写双指针就好
void swapchar(char *a,char *b){
char temp;
temp = *a;
*a= *b;
*b = temp;
}
void reverseString(char* s, int sSize){
int lo = 0,hi = sSize-1;
while(lo<hi){
swapchar(&s[lo],&s[hi]);
lo++;
hi--;
}
return;
}
解析:由于空格将字符串分串,采用while嵌套while的循环才能解决此问题,而且要记录每个字符串的长度,所以要设立两个计数器,一个记住开头,一个记住结尾,然后进行reserve就好了。
void swapchar(char *a,char *b){
char temp;
temp = *a;
*a= *b;
*b = temp;
}
char * reverseWords(char * s){
int start = 0;
int length = strlen(s);
while(start<length){
int cnt = start;//改变起点的方法:再加一个计数器
while(start<length&&s[start]!=' '){
start++;
}//防止overflow
int lo=cnt,hi=start-1;
while(lo<hi){
swapchar(&s[lo],&s[hi]);
lo++;
hi--;
}
start++;
}
return s;
}