《六月集训》第五天——双指针


前言

        
刷题坚持每一天,以下题目引用自:力扣(LeetCode)

💎一、题目一

🏆1.题目描述

原题链接:2000. 反转单词前缀

给你一个下标从 0 开始的字符串 word 和一个字符 ch 。找出 ch 第一次出现的下标 i ,反转 word 中从下标 0 开始、直到下标 i 结束(含下标 i )的那段字符。如果 word 中不存在字符 ch ,则无需进行任何操作。

  • 例如,如果 word = “abcdefd” 且 ch = “d” ,那么你应该 反转 从下标 0 开始、直到下标 3 结束(含下标 3 )。结果字符串将会是 “dcbaefd” 。

返回 结果字符串 。

示例 1:
输入:word = “abcdefd”, ch = “d”
输出:“dcbaefd”
解释:“d” 第一次出现在下标 3 。
反转从下标 0 到下标 3(含下标 3)的这段字符,结果字符串是 “dcbaefd” 。

🏆2.解题思路

🔑思路:

​         遍历到和ch相等的字符退出循环,字符进行左右交换。

🏆3.代码详解

char * reversePrefix(char * word, char ch){
    int i = 0, j = 0;
    char flag;
    while(1){
        if(word[j] == ch)
            break;
        else if(word[j] == '\0')
            return word;
        ++j;
    }
    while(i < j){
        flag = word[i];
        word[i] = word[j];
        word[j] = flag;
        ++i;
        --j;
    }
    return word;
}

💎二、题目二

🏆1.题目描述

原题链接:917. 仅仅反转字母

给你一个字符串 s ,根据下述规则反转字符串:

  • 所有非英文字母保留在原有位置。
  • 所有英文字母(小写或大写)位置反转。

返回反转后的 s 。

示例 1:
输入:s = “ab-cd”
输出:“dc-ba”

🏆2.解题思路

🔑思路:

​         对字符增加条件,不是大小写字符直接略过。

🏆3.代码详解

char * reverseOnlyLetters(char * s){
    int left = 0, right = strlen(s)-1;
    while(left < right){
        if(s[left] < 'A' || (s[left] > 'Z' && s[left] < 'a') || s[left] > 'z'){
            ++left;
            continue;
        }
        if(s[right] < 'A' || (s[right] > 'Z' && s[right] < 'a') || s[right] > 'z'){
            --right;
            continue;
        }  
        char cen = s[left];
        s[left] = s[right];
        s[right] = cen;
        ++left;
        --right;
    }
    return s;
}

💎三、题目三

🏆1.题目描述

原题链接:475. 供暖器

        冬季已经来临。 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖。
        在加热器的加热半径范围内的每个房屋都可以获得供暖。
        现在,给出位于一条水平线上的房屋 houses 和供暖器 heaters 的位置,请你找出并返回可以覆盖所有房屋的最小加热半径。
        说明:所有供暖器都遵循你的半径标准,加热的半径也一样。

示例 1:
输入: houses = [1,2,3], heaters = [2]
输出: 1
解释: 仅在位置2上有一个供暖器。如果我们将加热半径设为1,那么所有房屋就都能得到供暖。

🏆2.解题思路

🔑思路:

​        先排序,在位置里找每个房屋的最小绝对差,在最小绝对差里找最大的值返回。

🏆3.代码详解

#define max(a, b) ((a)>(b)?(a):(b))
#define min(a, b) ((a)<(b)?(a):(b))
int cmp(const void* q1, const void* q2){
    return *(int*)q1 - *(int*)q2;
}
int findRadius(int* houses, int housesSize, int* heaters, int heatersSize){
    qsort(houses, housesSize, sizeof(int), cmp);
    qsort(heaters, heatersSize, sizeof(int), cmp);
    int ans = 0;
    for(int i = 0, j = 0; i < housesSize; ++i){
        int ret = abs(houses[i]-heaters[j]);
        while(j < heatersSize-1 && (abs(houses[i] - heaters[j]) >= abs(houses[i] - heaters[j+1]))){
            ++j;
            ret = min(ret, abs(houses[i]-heaters[j]));
        }
        ans = max(ans, ret);
    }
    return ans;
}

💎四、题目四

🏆1.题目描述

原题链接:面试题 16.06. 最小差

        给定两个整数数组a和b,计算具有最小差绝对值的一对数值(每个数组中取一个值),并返回该对数值的差

示例 1:
输入:{1, 3, 15, 11, 2}, {23, 127, 235, 19, 8}
输出:3,即数值对(11, 8)

🏆2.解题思路

🔑思路:

​         先排序,对两数组值逐一比较取差,然后判断取最小差。

🏆3.代码详解

long long min(long long a, long long b){
    return a < b ? a : b;
}
int cmp(const void* a, const void* b)
{
    return (*(int*)a >= *(int*)b) ? 1 : -1;
}
int smallestDifference(int* a, int aSize, int* b, int bSize){
    qsort(a, aSize, sizeof(int), cmp);
    qsort(b, bSize, sizeof(int), cmp);
    long long ans = 2147483647;
    long long dfvl;
    int i = 0, j = 0;
    while(i < aSize && j < bSize){
        if(a[i] == b[j]) return 0;
        else if(a[i] < b[j]){
            dfvl = (long)b[j] - (long)a[i];  
            ++i;
        }
        else if(a[i] > b[j]){
            dfvl = (long)a[i] - (long)b[j];
            ++j;
        }
        ans = min(ans, dfvl);
    }
    return ans;
}

💎五、星球推荐

        星球链接:英雄算法联盟

星球里有什么?
        【朋友圈】一个极致精准的自律、编程、算法的小圈子。
        【算法集训】以月为单位组织算法集训,每天四题,风雨无阻。
        【排行榜】每天、每周都会有榜单,激励大家不断进步,不断成长。
        【个人规划】每个人都写好自己的规划,也可以查看他人的规划,时刻警醒自己不掉队。
        【打卡挑战】每日一题打卡、每日早起打卡、算法集训打卡、规划完成情况打卡。
在星球里做什么?
        目前星球人数达到520+,在星球里你能够遇到一群志同道合之人,因为都是花钱进来的,你不会看到任何浑水摸鱼的人,每个人都有自己的每月规划,星主每月都会组织算法集训,每天一起刷题,你可以看到别人的解题报告,取其之长,补己之短。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值