刷题 ------ 双指针

news2024/12/22 19:17:04

文章目录

  • 1.验证回文串 ||
  • 2.计数二进制字串
  • 3. 字符的最短距离
  • 4.按奇偶排序数组
  • 5.仅仅反转字母
  • 6. 奇偶排序数组 ||
  • 7.长按键入
  • 8. 递减字符匹配
  • 9.有序数组的平方
  • 10.复写零
  • 11.删除回文子序列
  • 12.检查单词是否为剧中其他单词的前缀
  • 13.交替合并的字符串
  • 14.反转单词前缀
  • 15.找出数组中的第一个回文字符串
  • 16.与对应负数同时存在的最大正整数
  • 16. 不同的平均值的数目
  • 17. 最多可以摧毁敌人城堡数目
  • 18.合并两个二维数组 - 求和法
  • 19.字典序最小回文串
  • 20.找出满足差值条件的洗标| **
  • 21.训练计划 |
  • 22.字符串中的单词反转
  • 23.动态口令
  • 24.字符串压缩
  • 25.合并排序数组

1.验证回文串 ||

在这里插入图片描述

  • 这道题说可以删除一个字符,也就是说,如果左右两边发现不同的时候,
  • 分别对其两个区间进行判断 [left + 1,right] || [left, right - 1];
  • 这两个区间分别 删除了当前 left 和 right。
  • 两个但凡有一个满足回文就行。
bool validPalindrome(char* s)
{
    int count = 0;
    int left = 0, right = strlen(s) - 1;
    while(left < right)
    {
        if(s[left] != s[right])
        {
            //不一样,因为只能删除一次,所以停止这次循环即可
            count++;
            break;
        }
        left++;
        right--;
    }
    if(count == 1)
    {
        int flagLeft = IsPalindrome(s,left+1,right);
        int flagRight = IsPalindrome(s,left,right - 1);
        return flagLeft || flagRight;
    }

    return true;
}

2.计数二进制字串

在这里插入图片描述

  • 额。。真得感谢老哥,好吧。 在这里插入图片描述
  • 看下图,第一组0出现了2 次 1出现了3次,但是能构成的字串只有01 0011 两种,意思就是说
  • 两者中小的那个才是这俩的极限,
  • 所以:min(2,3) + min(3,1) + min(1,2) = ans

在这里插入图片描述
我们当然可以专门用一个数组,来计算出上图中的第二行,但是也可以利用一个变量lastCount来维护,这样剩下了空间,也剩下了时间

int countBinarySubstrings(char* s)
{
    int i, len = strlen(s), ans = 0, lastCount = 0;
    while(i < len)
    {
        char c = s[i];
        int count = 0;
        //统计当前相同的0或者1出现的次数
        while(i < len && s[i] == c)
        {
            i++;
            count++;
        }
        //和上一个出现的进行比较
        ans += (lastCount < count ? lastCount : count);
        //更新前一个出现的次数
        lastCount = count;
    }
    return ans;
}

3. 字符的最短距离

在这里插入图片描述
我是说哈,咱有时候想不出来,就真别想了,就我在那里想半天,做了老多的 if else,总是有测试用例是错了,题解该看还是得看。

  • 遍历两边,从左到右遍历一遍,再从👉到左遍历。
  • 拿一个 j 下标来指向前一次的 c 字符出现的位置,
  • 第一次遍历,j 最开始在左边的时候,是 i - j的形式去计算距离,所以刚开始的 j 给一个小值(负值),这样 i - j 永远都会是一个很大的值,再第二次从右往左遍历的时候,他就会被新的小值给比下去。
  • 第二次遍历, j一定得是在右边记录c的位置,是 j - i的形式去计算距离,所以j刚开始就可以给一个比较大的值,这样 j - i 和第一次遍历后的值去比较,选择小的即可。
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* shortestToChar(char* s, char c, int* returnSize)
{
    int i,j;
    int len = strlen(s);
    int* ans = (int*)malloc(sizeof(int) * len);
    *returnSize = len;
    for (i = 0, j = -len; i < len; i++)
    {
        if(s[i] == c)
        {
            //j 记录这前一个 c 的下标
            j = i;
        }
        ans[i] = i - j;
    }

    for (i = len - 1, j = 2*len; i >= 0; i--)
    {
        if(s[i] == c)
        {
            j = i;
        }
        ans[i] = ans[i] < j - i ? ans[i] : j - i;
    }

    return ans;
}

4.按奇偶排序数组

在这里插入图片描述
办法有很多,你可以,对数组进行两次遍历,第一次存偶数,第二次存奇数,
还可以利用双指针 一次遍历的时候,是偶数的存前面,奇数存后面。
下面我同样也是用双指针,进行原地修改了直接,没开辟空间

  • 左边去找奇数,右边去找偶数,
  • 当左边奇数,右边是偶数的时候,交换他俩就好了
/**
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* sortArrayByParity(int* nums, int numsSize, int* returnSize)
{
    int i = 0, j = numsSize - 1;
    *returnSize = numsSize;
    while(i < j)
    {
        if(nums[i] % 2 == 0 || nums[i] == 0)
        {
            //左边找奇数
            i++;
        }   
        if(nums[j] % 2 != 0)
        {
            //右边找偶数
            j--;
        }
        if(i < j && nums[i] % 2 != 0 && nums[j] % 2 ==0)
        {
            //交换
            int tmp = nums[i];
            nums[i++] = nums[j];
            nums[j--] = tmp; 
        }
    }

    return nums;
}

5.仅仅反转字母

在这里插入图片描述

  • 双指针,左右两个,
  • 左边和右边,分别去找是字母的字符。
  • 找到之后进行交换即可
char* reverseOnlyLetters(char* s)
{
    int len = strlen(s);
    int left = 0, right = len - 1;

    while (left < right)
    {
        //两边同时去找字母
        while (left < len && !((s[left] >= 'a' && s[left] <= 'z') || (s[left] >= 'A' && s[left] <= 'Z')))
        {
            left++;
        }
        while ( right >= 0 && !((s[right] >= 'a' && s[right] <= 'z') || (s[right] >= 'A' && s[right] <= 'Z')))
        {
            right--;
        }

        if (left < right)
        {
            char tmp = s[left];
            s[left++] = s[right];
            s[right--] = tmp;
        }
    }

    return s;
}

6. 奇偶排序数组 ||

在这里插入图片描述

  • i 代表 偶数下标, j 代表奇数下标
  • 去依次遍历数组,如果发现偶数下标对应的数据不是偶数。
  • 那么就去动用 j 去找那个奇数下标不是奇数的。
  • 找到之后将这俩交换即可。
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* sortArrayByParityII(int* nums, int numsSize, int* returnSize)
{
    int i = 0,j = 1;    //i 表示偶数下标, j 表示奇数下标
    *returnSize = numsSize;
    for (i = 0; i < numsSize; i += 2)
    {
        //如果偶数下标,所对应的是数据是奇数
        if(nums[i] % 2 != 0)
        {
            //去找奇数下标对应的偶数
            while(nums[j] % 2 != 0)
            {   
                j += 2;
            }
            //这俩交换
            int tmp = nums[i];
            nums[i] = nums[j];
            nums[j] = tmp;
        }
    }
    return nums;
}

7.长按键入

在这里插入图片描述

  • 首先我的思路是这样的。
  • i 和 j 有一个大于自身的长度了就结束循环
  • 如果 i 都没走完,就说明肯定不行
  • 如果 j 没走完,那么就去判断它后面的字母是否与name结尾一致。如果有不一致的,则返回false
  • 然后中间过程中拿一个ch变量记录着当前相同的字母,就是下面这幅图的工作

在这里插入图片描述
代码如下:

bool isLongPressedName(char* name, char* typed)
{
    int i = 0, j = 0;
    int lenName = strlen(name);
    int lenTyped = strlen(typed);
    char ch = name[0];
    while(i < lenName && j < lenTyped)
    {
        if(name[i] == typed[j])
        {
            ch = name[i];
            i++;
            j++;
        }
        else
        {
            if(typed[j] != ch)
            {
                return false;
            }
            j++;
        }
    }
    //如果 j 没走完,去判断剩余的部分是否与最后一个相同
    while(j < lenTyped)
    {
        if(typed[j] != name[i - 1])
        {
            return false;
        }
        j++;
    }

    return i == lenName;
}

  • 而官方题解的话,优化了不少,
  • 首先在循环上,它的结束条件是 走完 j
  • 还有就是中间省去了我上面的ch变量,它使用typed[ j ] 和 typed[ j - 1 ]直接进行比较。
  • 还是官方的妙,(;´༎ຶД༎ຶ`)
  • (;´༎ຶД༎ຶ`)
  • (;´༎ຶД༎ຶ`)
  • (;´༎ຶД༎ຶ`)
bool isLongPressedName(char* name, char* typed)
{
    int i = 0,j = 0;
    int lenName = strlen(name), lenType = strlen(typed);
    
    while(j < lenType)
    {
        // i < lenName  ---   i 可能先走完
        if( i < lenName && name[i] == typed[j])
        {
            i++;
            j++;
        }
        else if(j > 0 && typed[j] == typed[j - 1])
        {
            // j > 0 ----- j 如果是 0 (0 - 1 = -1)ERROR
            j++;
        }
        else
        {
            return false;
        }
    }

    return i == lenName;
}

8. 递减字符匹配

在这里插入图片描述

  • 从题目和测试用例也能看出来,就是输出数组中最大的数是 len 最小的数十是 0.
  • 我们只需要遍历一遍字符串,如果是 I的话就把大的值赋值上去,反之赋值小的,完成后对应的指针进行移动即可。
    在这里插入图片描述
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* diStringMatch(char* s, int* returnSize)
{
    int len = strlen(s);
    int size = len + 1;
    int* ans = (int*)malloc(sizeof(int) * size);
    int i;
    int low = 0, high = len;
    for (i = 0; i < len; i++)
    {
        if(s[i] == 'I')
        {
            //当前位置小
            ans[i] = low++;
        }
        else if(s[i] == 'D')
        {
            //当前位置大
            ans[i] = high--;
        }
    }
    ans[i] = low;
    *returnSize = size;
    return ans;
}

9.有序数组的平方

在这里插入图片描述

  • 一组有序的数字,如果其还带负数,一定是两边数的平方最大嘛。
  • 所以,利用 i 和 j 分别表示表示数组左右两边的数。
  • 然后拿一个index当ans数组的下标,其index一定是从后往前赋值的(因为不管 i 和 j)算出来取的是那个大值。
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* sortedSquares(int* nums, int numsSize, int* returnSize)
{
    int* ans = (int*)malloc(sizeof(int)  * numsSize);
    *returnSize = numsSize;
    int i = 0, j = numsSize - 1,index; // i 和 j 分别为nums数组的前后指针,index为ans数组的索引
    for (index = numsSize - 1; index >= 0; index--)
    {
        if(pow(nums[j],2) > pow(nums[i],2))
        {
            ans[index] = pow(nums[j--],2);
        }
        else
        {
            ans[index] = pow(nums[i++],2);
        }
    }

    return ans;
}

10.复写零

在这里插入图片描述

  • 利用 i 和 j ,主要是i指针进行遍历,如果发现是0,那么j就进行自增的。当j大于或者等于了arrsize的时候停下来。
  • 然后在从 i 开始,往前倒着遍历的同时给相应的 j 去赋值
void duplicateZeros(int* arr, int arrSize)
{
    int i,j;    //j 随着 i 的对数组的遍历,最后将会代表调整后数组的末尾,
    for (i = 0,j = 0; i < arrSize; i++,j++)
    {
        if(arr[i] == 0)
        {
            j++;
        }
        if(j >= arrSize - 1)
        {
            //在数组原地调整,j不能超出去。
            break;
        }
    }

    if(j == arrSize)
    {
        // j 等于了 arrsize 就说明其最后一个元素是0,但是放不下了。
        arr[--j] = arr[i--];
        j--;
    }

    while(i >= 0)
    {
        if(arr[i] != 0)
        {
            //赋值即可
            arr[j--] = arr[i--];
        }
        else
        {
            //两个0写入
            arr[j--] = 0;
            arr[j--] = 0;
            i--; //然后i指向下一个
        }
    }
}

11.删除回文子序列

在这里插入图片描述

?????,就是说,如果这个字符串是回文的,只需要删除一次,不是回文的,可以全删a 和 全删 b 也就两次,题目中说的是子序列,不是字串
在这里插入图片描述

bool IsPalindrome(char* s)
{
    int left = 0, right = strlen(s) - 1;
    while(left < right)
    {
        if(s[left] != s[right])
        {
            return false;
        }
        left++;
        right--;
    }

    return true;
}


int removePalindromeSub(char* s)
{
    return IsPalindrom(s) ? 1 : 2;
}

12.检查单词是否为剧中其他单词的前缀

在这里插入图片描述

  • 首先得会分隔单词的区间[begin,end];
  • 用index 记录第几个单词。
  • 然后去判断当前这个单词的前缀是否满足searchWord的就好了
int isPrefixOfWord(char* sentence, char* searchWord)
{
    int len1 = strlen(sentence), len2 = strlen(searchWord);
    int i = 0,index = 1;//index 表示第几个单词
    while(i < len1)
    {
        int begin = i,end = begin;
        //分隔单词区间[begin,end];
        while(end < len1 && sentence[end] != ' ')
        {
            end++;
        }
        //判断
        int k = 0; // k 代表searchword的索引
        while(k < len2 && begin < end && sentence[begin] == searchWord[k])
        {
            begin++;
            k++;
        }
        if(k == len2)
        {
            return index;
        }

        i = end + 1;
        index++;
    }

    return -1;
}

13.交替合并的字符串

在这里插入图片描述

  • i 和 j 分别代表word1 和word2的起点,然后当发现有一个走完的时候。
  • 将另一个没走完的拷过去就好了。


char * mergeAlternately(char * word1, char * word2)
{
    int len1 = strlen(word1), len2 = strlen(word2);
    char* ans = (char*)malloc(sizeof(char) * (len1 + len2 + 1));
    int size = 0,i = 0, j = 0;
    while(i < len1 && j < len2)
    {
        ans[size++] = word1[i++];
        ans[size++] = word2[j++];
    }

    while(j < len2)
    {
        ans[size++] = word2[j++];
    }
    while(i < len1)
    {
        ans[size++] = word1[i++];
    }

    ans[size] = '\0';
    return ans;
}

14.反转单词前缀

在这里插入图片描述

  • 利用begin 和 end 两个下标去遍历word,如果end都走完了还没有发现目标ch,返回原来的。
  • 如果找到了,从begin 和 end 进行反转字串,并返回
char* reversePrefix(char* word, char ch)
{
    int len = strlen(word);
    int begin = 0, end = 0;
    while(end < len)
    {
        //word的中有字串
        if(word[end] == ch)
        {
            //进行反转即可
            while(begin < end)
            {
                char tmp = word[begin];
                word[begin++] = word[end];
                word[end--] = tmp;
            }
            return word;
        }
        end++;
    }


    return word;
}

15.找出数组中的第一个回文字符串

在这里插入图片描述

  • 嗯。。。。。
bool IsPalindrome(char* s)
{
    int left = 0, right = strlen(s) - 1;
    while(left < right)
    {
        if(s[left] != s[right])
        {
            return false;
        }
        left++;
        right--;
    }

    return true;
}



char* firstPalindrome(char** words, int wordsSize)
{
    int i;
    for (i = 0; i < wordsSize; i++)
    {
        if(IsPalindrome(words[i]))
        {
            return words[i];
        }
    }
    return "";
}

16.与对应负数同时存在的最大正整数

在这里插入图片描述

  • 先给数组尽心排序,然后利用 i 和 j 两和指针对数组进行遍历。
  • 其中 i 开始是指向负数的,如果它的绝对值小于j那么 j–。
  • 反之i++;
int cmp_int(const void* x,const void* y)
{
    return *(int*)x - *(int*)y;
}


int findMaxK(int* nums, int numsSize)
{
    qsort(nums,numsSize,sizeof(int),cmp_int);
    int i = 0, j = numsSize - 1;
    while(i < j)
    {
        if(-nums[i] > nums[j])
        {
            i++;
        }
        else if (-nums[i] < nums[j])
        {
            j--;
        }
        else 
        {
            return nums[j];
        }
    }
    
    return -1;
}

16. 不同的平均值的数目

在这里插入图片描述

  • 先排序,然后对利用两个指针,一前一后的去相加求和。
  • 记录有多少个是第一次出现就行。
int cmp_int(const void* x, const void* y)
{
    return *(int*)x - *(int*)y;
}


int distinctAverages(int* nums, int numsSize)
{
    qsort(nums,numsSize,sizeof(int),cmp_int);
    int* map = (int*)calloc(201,sizeof(int));
    int low = 0, high = numsSize - 1, count = 0;    
    while(low < high)
    {
        int sum = nums[low] + nums[high];
        //和如果一样,平均值肯定也一样。
        if(map[sum] == 0)
        {
            //记录第一次出现的次数
            map[sum++]++;
            count++;
        }
        low++;
        high--;
    }
    return count;
}

17. 最多可以摧毁敌人城堡数目

在这里插入图片描述

  • 这道题就是计算出1和-1之间的最大差距,
  • 在找到第一个 1 或者 -1 的时候,记录begin ,begin即是开始,也是结束
  • 比如1:相对于我方军队时开始,相对于敌方军队的话,不就是结束了嘛?
  • 然后再去找下一个出现的位置,如果他俩不相同的话,就记录其长度,否则就更换begin
int captureForts(int* forts, int fortsSize)
{
    int begin = -1,end,ans = 0;
    for(end = 0; end < fortsSize; end++)
    {
        if(forts[end] == 1 || forts[end] == - 1)
        {
            if(begin >= 0 && forts[begin] != forts[end])
            {
                ans = ans > end - begin - 1 ? ans : end - begin - 1;
            }
            //如果两者一致的话不进去求距离,而是更新位置,
            begin = end;
        }
    }

    return ans;
}

18.合并两个二维数组 - 求和法

在这里插入图片描述

  • 上面做过类似的题
  • 只不过这里变成了二维的了。
/**
 * Return an array of arrays of size *returnSize.
 * The sizes of the arrays are returned as *returnColumnSizes array.
 * Note: Both returned array and *columnSizes array must be malloced, assume caller calls free().
 */
int** mergeArrays(int** nums1, int nums1Size, int* nums1ColSize, int** nums2, int nums2Size, int* nums2ColSize, int* returnSize, int** returnColumnSizes)
{
    int** ans = (int**)malloc(sizeof(int*) * (nums1Size + nums2Size));
    *returnColumnSizes = (int*)malloc(sizeof(int) * (nums1Size + nums2Size));
    int size = 0,i = 0, j = 0;
    while(i < nums1Size && j < nums2Size)
    {
        ans[size] = (int*)malloc(sizeof(int) * 2);
        (*returnColumnSizes)[size] = 2;
        if(nums1[i][0] < nums2[j][0])
        {
            //赋nums1的值
            ans[size][0] = nums1[i][0];
            ans[size++][1] = nums1[i++][1];
        }
        else if(nums1[i][0] > nums2[j][0])
        {
            //
            ans[size][0] = nums2[j][0];
            ans[size++][1] = nums2[j++][1];
        }
        else
        {
            ans[size][0] = nums1[i][0];
            ans[size++][1] = nums1[i++][1] + nums2[j++][1];
        }
    }

    //将未遍历完的全部导入到后面去
    while(i < nums1Size)
    {
        ans[size] = (int*)malloc(sizeof(int) * 2);
        (*returnColumnSizes)[size] = 2;
        ans[size][0] = nums1[i][0];
        ans[size++][1] = nums1[i++][1];
    }

    while(j < nums2Size)
    {
        ans[size] = (int*)malloc(sizeof(int) * 2);
        (*returnColumnSizes)[size] = 2;
        ans[size][0] = nums2[j][0];
        ans[size++][1] = nums2[j++][1];
    }


    *returnSize = size;
    return ans;
}

19.字典序最小回文串

在这里插入图片描述

  • 回文的话就是左右两边取进行遍历,
  • 如果发现二者不一样,那么就赋值成他俩中那个较小的(最小回文串)。
char * makeSmallestPalindrome(char * s)
{
    int left = 0, right = strlen(s) - 1;
    while(left < right)
    {
        if(s[left] < s[right])
        {
            s[right] = s[left];
        }
        else if(s[left] > s[right])
        {
            s[left] = s[right];
        }

        left++;
        right--;
    }

    return s;
}

20.找出满足差值条件的洗标| **

在这里插入图片描述

  • 需要用两个指针分别记录着当前最大数和最小数的下标。
  • 然后j从所给的index开始,i 就从0索引出开始,这样子,他们同时加加,这样子index条件肯定是永远满足的。
  • 而val则是去循环内部去判断。
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* findIndices(int* nums, int numsSize, int indexDifference, int valueDifference, int* returnSize)
{
    int maxIndex = 0, miniIndex = 0; //这俩分别记录着数组中当前最大数的下标,和最小数的下标
    int* ans = (int*)malloc(sizeof(int) * 2);
    ans[0] = -1;
    ans[1] = -1;
    *returnSize = 2;
    int i,j;
    //i 和 j同时++,这样他俩的距离永远适合的,再循环内判断val即可
    for (i = 0, j = indexDifference; j < numsSize; j++,i++)
    {
        //更新其最小值和最大值的下标索引
        if(nums[maxIndex] < nums[i])
        {
            maxIndex = i;
        }
        else if(nums[miniIndex] > nums[i])
        {
            miniIndex = i;
        }

        if(nums[maxIndex] - nums[j] >= valueDifference)
        {
            ans[0] = maxIndex;
            ans[1] = j;
            return ans;
        }
        if(nums[j] - nums[miniIndex] >= valueDifference)
        {
            ans[0] = miniIndex;
            ans[1] = j;
            return ans;
        }

    }

    return ans;
}

21.训练计划 |

在这里插入图片描述

  • 双指针分别在左边找和右边找
  • 左边去找偶数,右边去找奇数。
  • 最后交换就好了
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* trainingPlan(int* actions, int actionsSize, int* returnSize)
{
    int left = 0, right = actionsSize - 1;
    *returnSize = actionsSize;
    while(left < right)
    {
       while(left < actionsSize && actions[left] % 2 != 0)
       {
           left++;
       }

       while(right >= 0 && actions[right] % 2 == 0)
       {
           right--;
       }

        if(left < right)
        {
            int tmp = actions[left];
            actions[left++] = actions[right];
            actions[right--] = tmp;
        }
    }

    return actions;
}

22.字符串中的单词反转

在这里插入图片描述

  • 从后往前开始遍历,用begin和end记录单词的开始和结尾,发现一个单词后,应该从该单词的结尾处开始拷贝。
  • 然后往后面赋值上一个空格。
  • 循环结束时候,将最后一个空格改成 **‘\0’**就好了
char* reverseMessage(char* message)
{   
    int len = strlen(message);

    char* ans = (char*)malloc(sizeof(char) * (len + 1));
    int begin,end;
    int size = 0;
    for (begin = len - 1, end = begin; end >= 0; end--)
    {
        while(end >= 0 && message[end] == ' ')
        {
            end--;
        }
        //调整新的单词开始位置
        begin = end;

        //去找单词的结束位置
        while(end >= 0 && message[end] != ' ')
        {
            end--;
        }

        //begin - end就是拷贝的大小
        if(begin - end != 0)
        {
            //有单词
            memcpy(ans + size,message + end + 1,sizeof(char) * (begin - end));
            size += (begin - end);
            ans[size++] = ' ';
        }
    }
    if(size == 0)
    {
        //如果一个单词都没有返回空串即可
        return "";
    }

    ans[--size] = '\0';
    return ans;
}

23.动态口令

在这里插入图片描述

  • 这道题,可以先拷贝target之后的,然后再拷贝tarrget之前的,就能解决了。
  • 下面我只拷贝一次,但是需要申请一下空间。
  • 将前面追加到原字符串末尾,最后返回password + target 就好了。
char* dynamicPassword(char* password, int target)
{
    int len = strlen(password);
    password = (char*)realloc(password,sizeof(char) * (len + target + 1));
    int i = 0, j = len;
    while(i < target)
    {
        password[j++] = password[i++];
    }
    password[j] = '\0';
    return password + target;
}

24.字符串压缩

在这里插入图片描述

  • 利用两个指针begin指向重复开始的起点,而end去找它的末尾。
  • 找到之后将其进行相应的赋值。
  • 最后计算两个字符串的长度,再决定返回哪一个。


char* compressString(char* S)
{
    int len = strlen(S);
    int begin = 0, end = 0;
    char* ans = (char*)malloc(sizeof(char) * ( 2 * len + 1));
    int size = 0;
    while(end < len)
    {
        int count = 0;
        //找结尾
        while(end < len && S[end] == S[begin])
        {
            count++;
            end++;
        }
        //当前重复的结束。
        ans[size++] = S[begin];
        size += sprintf(ans + size,"%d" ,count);
        //更新begin 指向新的位置
        begin = end;
    }
    ans[size] = '\0';   
    int len2 = strlen(ans);
    return len <= len2 ? S : ans;
}

25.合并排序数组

在这里插入图片描述

  • 利用 i 和 j 分别指向A 和B两个数组的数字末端,同时拿k去A数组的末端
  • 然后比较两者大小,哪一个大,哪一个赋值给k。
  • 最后循环结束,B数组中还有值的话,把它们全部移到A上面去。

void merge(int* A, int ASize, int m, int* B, int BSize, int n)
{
    int i = m - 1,j = n - 1,k = ASize - 1;
    while(i >= 0 && j >= 0)
    {
        if(A[i] > B[j])
        {
            A[k--] = A[i--]; 
        }
        else   
        {
            A[k--] = B[j--];
        }
    }

    while(j >= 0)
    {
        A[k--] = B[j--];
    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1394475.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿赵UE学习笔记——11、地形系统

阿赵UE学习笔记目录 大家好&#xff0c;我是阿赵。   继续学习虚幻引擎的用法&#xff0c;这次来学习一下虚幻引擎的地形系统的用法。 一、创建地形 在选项模式里面&#xff0c;选择地形&#xff1a; 进入到地形界面之后&#xff0c;需要先创建一个地形&#xff1a; 留意看…

npm依赖库备份

常用命令 设置默认使用本地缓存安装Nodejs时会自动安装npm&#xff0c;但是局路径是C:\Users\Caffrey\AppData\Roaming\npm默认的缓存路径是C:\Users\Caffrey\AppData\Roaming\npm-cache&#xff1b;查看npm的prefix和cache路径配置信息设置路径 设置默认使用本地缓存 npm con…

李沐《动手学深度学习》线性神经网络 softmax回归

系列文章 李沐《动手学深度学习》预备知识 张量操作及数据处理 李沐《动手学深度学习》预备知识 线性代数及微积分 李沐《动手学深度学习》线性神经网络 线性回归 目录 系列文章一、softmax回归&#xff08;一&#xff09;问题背景&#xff08;二&#xff09;网络架构&#xf…

路飞项目--02

补充&#xff1a;axios封装 # 普通使用&#xff1a;安装 &#xff0c;导入使用 const filmListreactive({result:[]}) axios.get().then() async function load(){let responseawait axios.get()filmList.resultresponse.data.results } # 封装示例&#xff1a;请求发出去之前…

【计算机组成与体系结构Ⅱ】虚拟存储器以及虚拟变换(实验)

实验7&#xff1a;虚拟存储器以及虚拟变换 一、实验目的 1&#xff1a;加深对虚拟存储器基本概念、基本组织结构以及基本工作原理的理解。 2&#xff1a;掌握页式、段式&#xff0c;段页式存储的原理以及地址变换的方法。 3&#xff1a;理解LRU与随机替换的基本思想。 二、…

easy Exsel导出

目录 一、首先引入依赖 二、然后封装一个VO 三、Controller层 四、Service实现类 引用样式 自适应列宽 自适应行高 五、测试 postman ​编辑 浏览器 异常 分配到这个任务了&#xff0c;写个小demo记录下&#xff0c;具体可参考EasyExcel官方文档 我用的是web上传…

redis数据安全(五)事务

一、概念&#xff1a; 1、介绍&#xff1a;Redis 事务的本质是一组命令的集合。事务支持一次执行多个命令&#xff0c;一个事务中所有命令都会被序列化。在事务执行过程&#xff0c;会按照顺序串行化执行队列中的命令&#xff0c;其他客户端提交的命令请求不会插入到事务执行命…

css实现动态水波纹效果

效果如下&#xff1a; 外层容器 (shop_wrap)&#xff1a; 设置外边距 (padding) 提供一些间距和边距 圆形容器 (TheCircle)&#xff1a; 使用相对定位 (position: relative)&#xff0c;宽度和高度均为 180px&#xff0c;形成一个圆形按钮圆角半径 (border-radius) 设置为 50%&…

Linux编译器--gcc和g++使用

gcc和g使用 一、gcc/g的作用1.1 预处理1.2 编译1.3 汇编1.4 链接 二、静态库和动态库三、make/Makefile3.1 make/Makefile3.2 依赖关系和依赖方法3.3 多文件编译3.4 make原理3.5 项目清理 四、linux下的第一个小程序-进度条4.1 行缓冲区的概念4.2 \r和\n4.3 进度条代码 一、gcc…

rt-thread修改全局中断屏蔽函数,解决内核频繁关闭中断影响精密计时问题

带rtt-nano实时操作系统的小板子需要读取单总线设备&#xff0c;使用软件延时吧&#xff0c;总是由于时隙不精确&#xff0c;通信不稳定。按说不稳定情况也不频繁&#xff0c;但考虑到未来需要对上百、上千米外的单总线设备通信&#xff0c;开发的时候偷个懒&#xff0c;到应用…

Jmeter后置处理器——JSON提取器

目录 1、简介 2、使用步骤 1&#xff09;添加线程组 2&#xff09;添加http请求 3&#xff09; 添加JSON提取器 1、简介 JSON是一种简单的数据交换格式&#xff0c;允许互联网应用程序快速传输数据。JSON提取器可以从JSON格式响应数据中提取数据、简化从JSON原始数据中提取特定…

《Unix环境高级编程》第三版源代码编译报错汇总(WSL)

文章目录 Error: unable to disambiguate: -dylib (did you mean --dylib ?)undefined reference to majorerror: ‘FILE’ has no member named ‘__pad’; did you mean ‘__pad5’?error: ‘FILE’ has no member named ‘_flag’; did you mean ‘_flags’?error: ‘FIL…

AAAI 2024 | TEx-Face,5秒内按需生成照片级3D人脸

本文介绍一篇来自浙江大学ReLER实验室的工作&#xff0c;"Controllable 3D Face Generation with Conditional Style Code Diffusion"&#xff0c;目前该文已被AAAI 2024录用。 论文题目&#xff1a; Controllable 3D Face Generation with Conditional Style Code D…

(C语言)冒泡排序

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>//实现buble_sort函数&#xff1b; void buble_sort(int arr[], int sz) {//初始化变量值&#xff1b;int i 0;//嵌套循环冒泡排序&#xff1b;//外层循环&…

adb、monkey的下载和安装

adb下载 官网网址&#xff1a;Downloads - ADB Shell 尽量不要下载最新的ADB Kits&#xff0c;因为兼容性可能不太好。 点击下载 ADB Kits 作者下载的版本是1.0.36 解压adb 到指定的目录即可。 然后把adb配置 环境变量。 检查adb是否安装成功

android 自定义八边形进度条

自定义八边形动画效果图如下 绘制步骤&#xff1a; 1.先绘制橙色底部八边形实心 2.黑色画笔绘制第二层&#xff0c;让最外层显示一条线条宽度即可 3.再用黄色画笔绘制黄色部分 4.使用渐变画笔根据当前进度绘制覆盖黄色部分 5.使用黑色画笔根据当前进度绘制刻度条 6.黑色画笔绘制…

C语言经典练习3——[NOIP2008]ISBN号码与圣诞树

前言 在学习C语言的过程中刷题是很重要的&#xff0c;俗话说眼看千遍不如手动一遍因为在真正动手去刷题的时候会暴露出更多你没有意识到的问题接下来我就为各位奉上两道我认为比较有代表性的题 1. [NOIP2008]ISBN号码 1.1 题目描述 每一本正式出版的图书都有一个ISBN号码与之对…

BKP备份寄存器读取

1.简介&#xff1a; BKP&#xff08;Backup&#xff09;备份寄存器是一种特殊的功能寄存器&#xff0c;用于存储某些设备的备份数据。这些数据通常是非常重要的&#xff0c;因此需要定期备份以防止意外丢失。 具体来说&#xff0c;BKP寄存器可以用于以下几种情况&#xff1a;…

100天精通鸿蒙从入门到跳槽——第6天:TypeScript 知识储备:类

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…

保留图片原画质图片无损放大

在数字时代&#xff0c;图片的放大和缩放是常见的操作。然而&#xff0c;传统的图片放大方法往往会导致图片质量的损失&#xff0c;使得图片的细节和清晰度降低。为了解决这个问题&#xff0c;水印云推出了一项新的功能——无损放大&#xff0c;让你可以在不损失图片质量的情况…