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

这篇具有很好参考价值的文章主要介绍了【每日挠头算法题(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)

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

点我直达~

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

思路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];
    }
};

总结

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

比如:排序,字符串逆置,字符串压缩等等,有关字符串的题都可以考虑一下双指针法
还有只要涉及到两个字符串中的两个字符的问题,都可以进行下标的模拟,或者计数法来实现。文章来源地址https://www.toymoban.com/news/detail-474879.html

到了这里,关于【每日挠头算法题(2)】压缩字符串|仅执行一次字符串交换能否使两个字符串相等的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Day28】力扣算法(超详细思路+注释) [1790. 仅执行一次字符串交换能否使两个字符串相等 ] [328. 奇偶链表 ][148. 排序链表]

    原题链接:1790. 仅执行一次字符串交换能否使两个字符串相等 题目描述 : 给你长度相等的两个字符串 s1 和 s2 。一次 字符串交换操作的步骤如下:选出某个字符串中的两个下标(不必不同),并交换这两个下标所对应的字符。 如果对 其中一个字符串 执行 最多一次字符串交

    2024年01月22日
    浏览(32)
  • 有限字符集的字符串压缩算法

    在开发中,经常有上报线上堆栈来分析处理线上问题的场景,所以,对堆栈的压缩和加密也是必不可少的。加密:可以使用AES对称加密算法,压缩:可以在上传时利用protobuf天生的压缩性对字符串进行压缩。 不过,出于对流量的节省和传输效率的提升,可以通过在堆栈上传前

    2024年02月11日
    浏览(44)
  • 字符串压缩加密算法(可逆)

    业务场景:App下单后的订单,需要在另一个内部系统中进行扫码打印。两个程序包括服务器之间网络不互通,所以想到了通过二维码携带内容做数据交互,但是将内容转为base64后发现字符串太长,放入二维码后二维码密度相当大,几乎无法被扫描,所以就想到了给字符串进行

    2024年02月11日
    浏览(38)
  • 【每日算法】【205. 同构字符串】

    ☀️博客主页:CSDN博客主页 💨本文由 我是小狼君 原创,首发于 CSDN💢 🔥学习专栏推荐:面试汇总 ❗️游戏框架专栏推荐:游戏实用框架专栏 ⛅️点赞 👍 收藏 ⭐留言 📝,如有错误请指正 📆 未来很长,值得我们全力奔赴更美好的生活✨ 老规矩,先介绍一下 Unity 的科

    2024年02月11日
    浏览(32)
  • 【力扣·每日一题】2085.统计出现过一次的公共字符串(模拟 哈希表 优化 C++ Go)

    题目链接 给你两个字符串数组 words1 和 words2 ,请你返回在两个字符串数组中 都恰好出现一次 的字符串的数目。 输入:words1 = [“leetcode”,“is”,“amazing”,“as”,“is”], words2 = [“amazing”,“leetcode”,“is”] 输出:2 解释: “leetcode” 在两个数组中都恰好出现一次,计入答

    2024年01月21日
    浏览(37)
  • 每日OJ题_算法_滑动窗口⑥_力扣438. 找到字符串中所有字母异位词

    目录 力扣438. 找到字符串中所有字母异位词 解析及代码1 解析及代码2 438. 找到字符串中所有字母异位词 - 力扣(LeetCode) 难度 中等 给定两个字符串  s  和  p ,找到  s   中所有  p   的  异位词  的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 异位词  指由

    2024年01月24日
    浏览(34)
  • ( 字符串) 205. 同构字符串 ——【Leetcode每日一题】

    难度:简单 给定两个字符串 s 和 t ,判断它们是否是同构的。 如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。 每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个

    2024年02月02日
    浏览(34)
  • MFC简单字符串压缩程序

    一个mfc简单字符串压缩程序;按以下情况进行压缩; 1 仅压缩连续重复出现的字符。比如”abcbc”无连续重复字符,压缩后还是”abcbc”。 2 压缩的格式为”字符重复的次数+字符”。例如,”xxxyyyyyyz”压缩后就成为”3x6yz”。

    2024年02月07日
    浏览(28)
  • (字符串 ) 459. 重复的子字符串——【Leetcode每日一题】

    难度:简单 给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。 示例 1: 输入: s = “abab” 输出: true 解释: 可由子串 “ab” 重复两次构成。 示例 2: 输入: s = “aba” 输出: false 示例 3: 输入: s = “abcabcabcabc” 输出: true 解释: 可由子串 “abc” 重复四次构

    2024年02月07日
    浏览(33)
  • 每日一题——字符串变形

    题目 对于一个长度为 n 字符串,我们需要对它做一些变形。 首先这个字符串中包含着一些空格,就像\\\"Hello World\\\"一样,然后我们要做的是把这个字符串中由空格隔开的单词反序,同时反转每个字符的大小写。 比如\\\"Hello World\\\"变形后就变成了\\\"wORLD hELLO\\\"。 需要考虑字符串结尾是空

    2024年02月13日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包