【每日挠头算法题(2)】压缩字符串|仅执行一次字符串交换能否使两个字符串相等

简介: 【每日挠头算法题(2)】压缩字符串|仅执行一次字符串交换能否使两个字符串相等

一、压缩字符串

点我直达~

思路

使用双指针法

大致过程如下:

  • 使用双指针,分别读(read),写(write)指针,读指针不断向后走,当read指针走到最后位置处时,或read和read的下一个位置与当前位置不相等时,说明该read指针走到了某一串相同子串的最后位置处。
  • 此时write指针开始记录具体的字符,给定一个left指针记录当前位置,此时每一个子串的长度都是 read - left +1
  • 使用短除法将子串的长度记录下来,再进行逆置即可。

具体操作如下:

  • 1.给定两个指针write 和 left(left指针记录每一个子串的开始位置),分别指向第一个元素的位置。
  • 2.使用read指针,遍历字符串,当read遇到其后面一个字符与当前字符不等,或者read走到末尾时,此时将write指针记录当前子串的字符,以及长度,那就让write一边记录一边往后走。
  • 3.当write指针开始记录子串的长度时,给一个下标begin,这个begin就是记录子串的长度的起始位置,比如一个串的长度为:123,需要记录到chars数组的是[“1”,“2”,“3”],begin记录着"1"下标的位置。
  • 4.使用短除法将某一个串的长度的每一位记录下来,然后逆置,逆置的开始是begin,结尾是write。
  • 5.因为write总是向后走,知道走到记录完所有的字符以及每一个相同的字符串的长度,则最终返回write的长度即可

具体代码如下:

class Solution {
public:
    int compress(vector<char>& chars) 
    {
        int write = 0,left = 0;
        for(int read = 0;read<chars.size();++read)
        {
            if(read == chars.size()-1 ||
             chars[read]!=chars[read+1])
            {   
                chars[write++] = chars[read];//存储字符
                int begin = write; // 逆置的左下标
                int n = read - left + 1 ; 
                if(n>1)
                {
                    while(n)
                    {
                        chars[write++] = (n%10) + '0';
                        n/=10;
                    }
                    //逆置的右下标是write
                    reverse(&chars[begin],&chars[write]);
                }
                left = read+1;
            }
        }
        return write;
    }
};

时间复杂度:O(n),空间复杂度O(1)

二、仅执行一次字符串交换能否使两个字符串相等

点我直达~

思路1:计数法

  • 情况1:如果两个字符串的长度不同,那么不管怎么交换一定不等,返回false
  • 情况2:如果两个字符串的长度相同:
  • 情况1:如果不相同的字符超过两个,或者不相同的字符只有一个,那么两个字符串不管怎么交换字符一定不等,返回false
  • 情况2:如果不相同的字符恰好为两个,此时有两种方法解决:
  • 1.交换这两个不相同的字符的位置,如果交换后s1 == s2,返回true,否则false。
  • 2.判断 s1[i] == s2[j] ,s1[j] == s2[i]是否满足即可。

具体请看下面代码:

class Solution {
public:
    bool areAlmostEqual(string s1, string s2)
    {
        //1.相等,true
        if(s1 == s2)
            return true;
        //2.长度不等,false
        if(s1.size() != s2.size())
            return false;
        //3.遍历s1和s2,如果发现有两个以上字母不同,不管怎么交换都不等       
        vector<int> v1; // 两个下标
        int count = 0;//计算s1和s2有几个不等的字母
        for(int i = 0;i<s1.size();++i)
        {
            if(s1[i]!=s2[i])
            {
                ++count;
                v1.push_back(i);
            }
        }
        //如果不是只有两个字母不同,不管怎么交换一定不等。
        if(count !=2)
            return false;
        return s1[v1[0]] == s2[v1[1]] && 
        s1[v1[1]] == s2[v1[0]] ;
        //下面的操作也可
         //swap(s2[v1[0]],s2[v1[1]]);
        // if(s1 == s2)
        //     return true;
        // return false;
    }
};

思路2:模拟法

模拟法整体思路与计数法大致相同

给定两个初始值pos1 ,pos2均为 -1,记录两个字符串不同的字符的下标。

  • 如果不同位置超过两个或者只有一个,返回false
  • 如果不同位置为两个或者没有不同位置,返回true

具体请看下面代码:

class Solution {
public:
    bool areAlmostEqual(string s1, string s2)
    {
        int n = s1.size(),pos1 = -1,pos2 = -1;
        for(int i = 0;i<n;++i)
        {
            if(s1[i] == s2[i])
                continue;
            if(pos1 == -1)
                pos1 = i;
            else if(pos2 == -1)
                pos2 = i;
            //该情况是超过两个不同的字符
            else
                return false;
        }
            //该情况是没有不同的字符
        if(pos1 == -1)
            return true;
            //该情况是只有一个不同的字符
        if(pos2 == -1)
            return false;
            //该情况是正常情况
        return s1[pos1] == s2[pos2] && s1[pos2] == s2[pos1];
    }
};

总结

通过写今天的两道题,重新认识了双指针法的厉害的地方,哪哪都可以考虑双指针法。

比如:排序,字符串逆置,字符串压缩等等,有关字符串的题都可以考虑一下双指针法

还有只要涉及到两个字符串中的两个字符的问题,都可以进行下标的模拟,或者计数法来实现。

相关文章
|
20天前
|
存储 人工智能 自然语言处理
Delta-CoMe:清华联合OpenBMB等高校开源的新型增量压缩算法
Delta-CoMe是由清华大学NLP实验室联合OpenBMB开源社区、北京大学和上海财经大学提出的新型增量压缩算法。该算法通过结合低秩分解和低比特量化技术,显著减少了大型语言模型的存储和内存需求,同时保持了模型性能几乎无损。Delta-CoMe特别适用于处理数学、代码和多模态等复杂任务,并在推理速度上有所提升。
55 6
Delta-CoMe:清华联合OpenBMB等高校开源的新型增量压缩算法
|
4月前
|
算法
【算法】滑动窗口——找到字符串中所有字母异位词
【算法】滑动窗口——找到字符串中所有字母异位词
|
2月前
|
算法
两个字符串匹配出最长公共子序列算法
本文介绍了最长公共子序列(LCS)问题的算法实现,通过动态规划方法求解两个字符串的最长公共子序列,并提供了具体的编程实现细节和示例。
97 1
两个字符串匹配出最长公共子序列算法
|
1月前
|
存储 JSON 算法
TDengine 检测数据最佳压缩算法工具,助你一键找出最优压缩方案
在使用 TDengine 存储时序数据时,压缩数据以节省磁盘空间是至关重要的。TDengine 支持用户根据自身数据特性灵活指定压缩算法,从而实现更高效的存储。然而,如何选择最合适的压缩算法,才能最大限度地降低存储开销?为了解决这一问题,我们特别推出了一个实用工具,帮助用户快速判断并选择最适合其数据特征的压缩算法。
55 0
|
2月前
|
算法 安全 Java
介绍一下比较与交换算法
【10月更文挑战第20天】介绍一下比较与交换算法
19 0
|
4月前
|
算法 Java
掌握算法学习之字符串经典用法
文章总结了字符串在算法领域的经典用法,特别是通过双指针法来实现字符串的反转操作,并提供了LeetCode上相关题目的Java代码实现,强调了掌握这些技巧对于提升算法思维的重要性。
|
4月前
|
算法 C++
惊爆!KPM算法背后的秘密武器:一行代码揭秘字符串最小周期的终极奥义,让你秒变编程界周期大师!
【8月更文挑战第4天】字符串最小周期问题旨在找出字符串中最短重复子串的长度。KPM(实为KMP,Knuth-Morris-Pratt)算法,虽主要用于字符串匹配,但其生成的前缀函数(next数组)也可用于求解最小周期。核心思想是构建LPS数组,记录模式串中每个位置的最长相等前后缀长度。对于长度为n的字符串S,其最小周期T可通过公式ans = n - LPS[n-1]求得。通过分析周期字符串的特性,可证明该方法的有效性。提供的C++示例代码展示了如何计算给定字符串的最小周期,体现了KPM算法在解决此类问题上的高效性。
92 0
|
18天前
|
算法
基于WOA算法的SVDD参数寻优matlab仿真
该程序利用鲸鱼优化算法(WOA)对支持向量数据描述(SVDD)模型的参数进行优化,以提高数据分类的准确性。通过MATLAB2022A实现,展示了不同信噪比(SNR)下模型的分类误差。WOA通过模拟鲸鱼捕食行为,动态调整SVDD参数,如惩罚因子C和核函数参数γ,以寻找最优参数组合,增强模型的鲁棒性和泛化能力。
|
24天前
|
机器学习/深度学习 算法 Serverless
基于WOA-SVM的乳腺癌数据分类识别算法matlab仿真,对比BP神经网络和SVM
本项目利用鲸鱼优化算法(WOA)优化支持向量机(SVM)参数,针对乳腺癌早期诊断问题,通过MATLAB 2022a实现。核心代码包括参数初始化、目标函数计算、位置更新等步骤,并附有详细中文注释及操作视频。实验结果显示,WOA-SVM在提高分类精度和泛化能力方面表现出色,为乳腺癌的早期诊断提供了有效的技术支持。
|
4天前
|
供应链 算法 调度
排队算法的matlab仿真,带GUI界面
该程序使用MATLAB 2022A版本实现排队算法的仿真,并带有GUI界面。程序支持单队列单服务台、单队列多服务台和多队列多服务台三种排队方式。核心函数`func_mms2`通过模拟到达时间和服务时间,计算阻塞率和利用率。排队论研究系统中顾客和服务台的交互行为,广泛应用于通信网络、生产调度和服务行业等领域,旨在优化系统性能,减少等待时间,提高资源利用率。