算法通关村第十二关—字符串冲刺题(黄金)

           字符串冲刺题

一、最长公共前缀

 LeetCode14 编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串""

java 复制代码
示例1:
输入:strs=["flower","fLow","flight"]
输出:"fL"
示例2:
输入:strs=["dog","racecar'","car"]
输出:""
解释:输入不存在公共前缀。

 根据题目内容,可以很明显看出两种思路,一种是纵向比较,一种是横向比较。

 先看第一种的实现方法,竖着比较。纵向扫描时,从前往后遍历所有字符串的每一列,比较相同列上的字符是否相同,如果相同则继续对下一列进行比较,如果不相同则当前列不再属于公共前缀,当前列之前的部分为最长公共前缀。

java 复制代码
public String longestCommonPrefix(String[] strs){
    if (strs == null || strs.length == 0){
        return "";
    }
    int length = strs[0].length();
    int count = strs.length;
    for(int i = 0; i < length; i++){
        char c = strs[0].charAt(i);
        for (int j = 1; j < count; j++){
            if (i == strs[j].length() || strs[j].charAt(i) != c){
                return strs[0].substring(0,i);
            }
        }
    }
    return strs[0]
}

 第二种是横着依次比较,依次遍历字符串数组中的每个字符串,对于每个遍历到的字符串,更新最长公共前缀(其实就是看是否要缩短,一定不会变长),当遍历完所有的字符串以后,即可得到字符串数组中的最长公共前缀。如果在尚未遍历完所有的字符串时,最长公共前缀已经是空串,则最长公共前缀一定是空串,因此不需要继续遍历剩下的字符串,直接返回空串即可。

java 复制代码
public String longestCommonPrefix(String[] strs){
    if (strs ==null || strs.length == 0){
        return "";
    }
    String prefix = strs[0];
    int count = strs.length;
    for (int i = 1; i < count; i++){
        prefix = longestCommonPrefix(prefix,strs[i]);
        if(prefix.length() == 0) break;
    }
    return prefix;
}
public String longestCommonPrefix(String str1,String str2){
    int length = Math.min(str1.length(),str2.length());
    int index = 0;
    while (index < length && str1.charAt(index) == str2.charAt(index)){
        index++;
        return str1.substring(0,index);
    }
}

二、字符串压缩问题

 LeetCode443给你一个字符数组chars,请使用下述算法压缩:

 从一个空字符串s开始。对于chars中的每组连续重复字符:

1.如果这一组长度为1,则将字符追加到s中。

2.否则,需要向S追加字符,后跟这一组的长度。压缩后得到的字符串S不应该直接返回,需要转储到字符数组chars中。需要注意的是,如果组长度为10或10以上,则在chars数组中会被拆分为多个字符。

 请在修改完输入数组后,返回该数组的新长度。你必须设计并实现一个只使用常量额外空间的算法来解决此问题。

java 复制代码
示例1:
输入:chars=["a","a","b","b","c","c","c"]
输出:返回6,输入数组的前6个字符应该是:["a","2","b","2","c","3"]
解释:
"aa"被"a2"替代。"bb"被"b2"替代。"ccc"被"c3"替代。
示例2:
输入:chars=["a"]
输出:返回1,输入数组的前1个字符应该是:["a"]
解释:
没有任何字符串被替代。
示例3:
输入:chars=["a","b","b","b","b","b","b","b","b","b","b","b","b"]
输出:返回4,输入数组的前4个字符应该是:["a","b","1","2"]。
解释:
由于字符"a"不重复,所以不会被压缩。"bbbbbbbbbbbb"被"b12"替代。
注意每个数字在数组中都有它自己的位置。

 这个题貌似采用双指针策略来处理就行,但是再分析发现三个指针才够。两个进行正常点扫描,还有一个用来确定修改的位置

 这里还有一个问题,就是长度可能超过0,因此还要实现将数字转化为字符串写入到原字符串的功能。这里我们采用短除法将子串长度倒序写入原字符串中,然后再将其反转即可。

java 复制代码
class Solution {
    public int compress(char[] chars) {
        int left = 0,right = 0, change = 0;
        int len = chars.length;
        //if(len == 1)return 1;
        while(right < len){
            while(right < len && chars[left] == chars[right]) right++;
            
            //该字符的数量
            int sum = right - left;
            //存入该字符
            chars[change] = chars[left];
            change++;
            int prechange = change;
            //将字符数量逐位存入
            if(sum != 1){
                int sum1 = sum;
                while(sum1 > 0){
                    chars[change] = (char) (sum1 % 10 + '0');
                    sum1 /= 10;
                    change++;
                }
                //反转sum,前面存的时候是从低位存到高位,与题目要求相反
                if(sum >= 10){
                    int nowchange = change - 1;
                    while(prechange < nowchange){
                        char temp = chars[prechange];
                        chars[prechange] = chars[nowchange];
                        chars[nowchange] = temp;
                        prechange++;
                        nowchange--;
                    }
                }
            }
            left = right;
        }
        return change;
    }
}
相关推荐
AI多Agent协作实战派7 小时前
AI多Agent协作系统实战(十七):凌晨4点,我的AI系统在“假装工作“——3个bug同时爆炸的5小时
java·前端·bug
gaolei_eit8 小时前
Java+Ai+vue
java·spring·maven
qq_2518364578 小时前
基于java Web 动漫视频网站毕业论文
java·开发语言·前端
LayZhangStrive8 小时前
JUC相关的函数、注解、变量杂记
java·面试·多线程·juc
未秃头的程序猿8 小时前
给公司做了个AI客服Agent,用的Spring AI 1.0,3天上线领导拍板了
java·后端·ai编程
来一碗刘肉面8 小时前
栈的应用(表达式求值)
数据结构·算法
曹牧8 小时前
Eclipse 批量文本替换
java·ide·eclipse
程序员清风8 小时前
OpenAI官方发布最新提示词技巧!
java·后端·面试
一只枫林8 小时前
MySQL内、外连接知识点汇总
java·前端·数据库
梅头脑8 小时前
写了3年CRUD,volatile和synchronized的区别还是答不清——直到我画出了这张三性两锁边界图
java