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),可以的:

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

  • 每个字符si到其左侧最近的字符 c 的距离。
  • 每个字符si到其右侧最近的字符 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;
    }
};
相关推荐
Tisfy1 天前
LeetCode 2095.删除链表的中间节点:两次遍历 / 一次遍历(快慢指针)
算法·leetcode·链表·题解·双指针
啦啦啦啦啦zzzz5 天前
算法总结(双指针)
c++·算法·双指针
j7~8 天前
【算法】专题一:双指针之移动零,复写零,快乐数
数据结构·c++·算法·双指针·快乐数·移动零·复写零
江屿风16 天前
C++OJ题经验总结(竞赛)4
开发语言·c++·笔记·算法·dp·双指针
8Qi817 天前
LeetCode 209. 长度最小的子数组(Minimum Size Subarray Sum)
java·算法·leetcode·双指针·滑动窗口
BestOrNothing_201517 天前
C++零基础到工程实战(5.2.6):函数与数组和数组引用
c++·数组·函数·数组引用·返回数组·参数数组
happymaker062619 天前
LeetCodeHot100——盛水最多的容器
数据结构·算法·leetcode·双指针·hot100
像素猎人22 天前
洛谷题B3882:求回文数【双指针】
算法·双指针
我还记得那天23 天前
数组的2个应用举例
c语言·开发语言·二分查找·数组
量子炒饭大师1 个月前
【优化算法】滑动窗口的「义体化」重构 ——【滑动窗口】何为滑动窗口?滑动窗口算法的核心目的是什么?
c++·算法·重构·优化算法·双指针·滑动窗口