Leetcode算法入门 双指针

轮转数组

给你一个数组,将数组中的元素向右轮转 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;
}

Supongo que te gusta

Origin blog.csdn.net/rick030224/article/details/121988423
Recomendado
Clasificación