821. 字符的最短距离 - 力扣

1. 题目

给你一个字符串 s 和一个字符 c ,且 cs 中出现过的字符。

返回一个整数数组 answer ,其中 answer.length == s.lengthanswer[i]s 中从下标 i 到离它 最近 的字符 c距离

两个下标 ij 之间的 距离abs(i - j) ,其中 abs 是绝对值函数。

2. 示例

3. 分析

我们先尝试一下暴力解法:将目标字符每次出现的位置保存到数组中,然后遍历字符串依次比较每个字符与目标字符每次出现的位置进行比较,寻找较小值即可

cpp 复制代码
class Solution {
public:
    vector<int> shortestToChar(string s, char c) {
        vector<int> index;
        vector<int> ans;
        int n = s.size();

        // 记录目标字符出现的位置
        for(int i = 0; i < n; i++)
        {
            if(s[i] == c)
            {
                index.push_back(i);
            }
        }

        // 遍历字符串,对每个字符与目标字符出现下标进行比较,寻找较小值
        for(int i = 0; i < n; i++)
        {
            int minres = INT_MAX;
            for(int j = 0; j < index.size(); j++)
            {
                minres = min(minres, abs(index[j]-i));
            }
            ans.push_back(minres);
        }
        return ans;
    }
};

时间复杂度:O(N2)


能不能做到O(N),可以的:

问题可以转换成,对 每个字符s[i] 的下标 i,求

  • 每个字符s[i]到其左侧最近的字符 c 的距离。
  • 每个字符s[i]到其右侧最近的字符 c 的距离。

这两者的较小值。

分别对字符串从左往右、从右往左遍历。

从左往右:在遍历的同时记录二者的距离,也需更新目标字符的下标。但在刚开始遍历时,目标字符可能不存在,所以二者距离也因此不能记录,所以为了记录二者的距离,我们可以使用 -n 初始化目标字符下标,这里 n 是 字符串的长度,距离就为 abs(index - i)。若找到第一个目标字符,二者距离也为 abs(index - i)。

从右往左:同理。初始化目标字符下标为 2n**,** 这里 n 是 字符串的长度。顺便比较此时二者距离与从左往右遍历时二者距离哪个为较小者。

cpp 复制代码
class Solution {
public:
    vector<int> shortestToChar(string s, char c) {
        int n = s.size();
        vector<int> ans(n);
        
        // 从左往右
        for(int i = 0, index = -n; i < n; i++)
        {
            if(s[i] == c) index = i;
            ans[i] = i - index;
        }

        // 从右往左
        for(int i = n - 1, index = 2*n; i >= 0; i--)
        {
            if(s[i] == c) index = i;
            ans[i] = min(ans[i], index - i);
        }
        return ans;
    }
};
相关推荐
睡不醒的kun2 天前
不定长滑动窗口-求子数组个数
数据结构·c++·算法·leetcode·职场和发展·双指针·滑动窗口
伟大的车尔尼3 天前
双指针题目:复写零
双指针
拾光Ծ4 天前
【优选算法】双指针算法:专题二
c++·算法·双指针·双指针算法·c++算法·笔试面试
沉默-_-5 天前
力扣hot100普通数组(1)--C++
java·数据结构·算法·leetcode·数组
CappuccinoRose6 天前
React框架学习文档(三)
前端·react.js·ui·数组·标签·属性·jsx
艾莉丝努力练剑6 天前
【优选算法必刷100题】第007~008题(双指针算法):三数之和、四数之和问题求解
linux·算法·双指针·优选算法
老鼠只爱大米8 天前
LeetCode经典算法面试题 #24:两两交换链表中的节点(迭代法、递归法等多种实现方案详细解析)
算法·leetcode·链表·递归·双指针·迭代·链表交换
沉默-_-8 天前
力扣hot100双指针专题解析2(C++)
java·c++·算法·蓝桥杯·双指针
老鼠只爱大米9 天前
LeetCode经典算法面试题 #19:删除链表的倒数第N个结点(双指针、栈辅助法等多种实现方案详细解析)
算法·leetcode·链表·双指针·删除链表节点·一趟扫描
2401_8414956410 天前
【LeetCode刷题】删除链表的倒数第N个结点
数据结构·python·算法·leetcode·链表·遍历·双指针