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;
    }
};
相关推荐
暴风鱼划水2 小时前
算法题(Python)数组篇 | 6.区间和
python·算法·数组·区间和
課代表7 小时前
VB.Net 常用函数
字符串·类型转换·数组·函数·vb.net·日期时间·条件
課代表1 天前
JavaScript 中获取二维数组最大值
javascript·max·数组·递归·array·最大值·二维
SamHou01 天前
奶奶都能看懂的 C++ —— 数组与指针
指针·数组·cpp
还是码字踏实3 天前
基础数据结构之数组的双指针技巧之对撞指针(两端向中间):三数之和(LeetCode 15 中等题)
数据结构·算法·leetcode·双指针·对撞指针
伟大的车尔尼5 天前
双指针题目:按奇偶排序数组
双指针
苏纪云7 天前
算法<C++>——双指针 | 滑动窗口
数据结构·c++·算法·双指针·滑动窗口
苏纪云12 天前
算法<C++>——双指针操作链表
c++·算法·链表·双指针
苏纪云13 天前
数据结构<C++>——数组
java·数据结构·c++·数组·动态数组