算法通关村-----字符串冲刺题

最长公共前缀

问题描述

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

问题分析


直观上来看,有竖直和水平两种方式,竖直方式是指我们依次比较所有字符串的第一个字符,如果相同,继续比较所有字符串的下一个字符,直至不相同或者有一个字符串遍历结束。水平方式是指可以先比较前两个字符的最长公共前缀,然后在比较前两个字符的最长公共前缀,与第三个字符的公共前缀,以此类推。同时,采用水平方式时,我们可以使用归并的方式,两两一组找最长公共前缀,然后再进行归并。

代码实现

竖直方式

java 复制代码
public String longestCommonPrefix(String[] strs) {
    StringBuilder sb = new StringBuilder();
    int len = strs.length;
    int n = strs[0].length();
    for (int i = 0; i < n; i++) {
        char c = strs[0].charAt(i);
        for (int j = 1; j < len; j++) {
            if (i >= strs[j].length() || strs[j].charAt(i) != c){
                return sb.toString();
            }
        }
        sb.append(c);
    }
    return sb.toString();
}

水平方式

java 复制代码
public String longestCommonPrefix(String[] strs) {
     int len = strs.length;
     if (len == 1) {
         return strs[0];
     }
     String prefix = longestCommonPrefix(strs[0], strs[1]);
     for (int i = 2; i < len; i++) {
         prefix = longestCommonPrefix(prefix, strs[i]);
     }
     return prefix;
 }

 public String longestCommonPrefix(String str1, String str2) {
     StringBuilder sb = new StringBuilder();
     int i = 0;
     int j = 0;
     while (i < str1.length() && j < str2.length()) {
         if(str1.charAt(i) == str2.charAt(j)){
             sb.append(str1.charAt(i));
             i++;
             j++;
         }else {
             return sb.toString();
         }
     }
     return sb.toString();
 }

压缩字符串

问题描述

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

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

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

否则,需要向 s 追加字符,后跟这一组的长度。

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

请在 修改完输入数组后 ,返回该数组的新长度。

你必须设计并实现一个只使用常量额外空间的算法来解决此问题。

详见leetcode443

问题分析

可以设置两个指针,用于寻找重复字符的起始和结束位置,同时在设置一个指针,用于设置写入位置,遍历字符数组,但个字符直接追加,重复字符,写入当前字符和出现次数,对于两位以上的出现次数,可以先逆序写入,然后再反转

java 复制代码
public int compress(char[] chars) {
    int left = 0;
    int right = 0;
    int write = 0;
    while (right < chars.length) {
        while (right < chars.length && chars[right] == chars[left]) {
            right++;
        }
        if (right - left == 1) {
            chars[write++] = chars[left];
            left = right;
        } else {
            int count = right - left;
            chars[write++] = chars[left];
            int start = write;
            while (count != 0) {
                int num = count % 10;
                chars[write++] = (char) ('0' + num);
                count/=10;
            }
            reverse(chars, start, write - 1);
            left = right;
        }
    }
    return write;
}
public void reverse(char[] chars, int left, int right) {
    while (left < right) {
        char temp = chars[left];
        chars[left] = chars[right];
        chars[right] = temp;
        left++;
        right--;
    }
}
相关推荐
好评笔记10 小时前
深度学习面试八股——循环神经网络RNN
人工智能·rnn·深度学习·神经网络·算法·机器学习·aigc
凯瑟琳.奥古斯特10 小时前
力扣1003题C++解法详解
开发语言·c++·算法·leetcode·职场和发展
计算机安禾10 小时前
【算法分析与设计】第48篇:流算法与数据概要技术
java·服务器·网络·数据库·算法
hunterkkk(c++)10 小时前
SPFA最短路径算法(c++)
java·c++·算法
weixin_4462608510 小时前
HANDOFF:基于蒸馏互补教师的人形机器人任务空间整体控制
人工智能·算法·机器人
商业模式源码开发11 小时前
知识付费推三返一模式详解:规则设计、分红算法与合规架构
算法·架构·推三返一
fengfuyao98511 小时前
基于MATLAB的HHT变换完整实现(含EMD分解与三维时频谱生成)
开发语言·算法·matlab
剑挑星河月11 小时前
98.验证二叉搜索树
java·算法·leetcode
罗超驿11 小时前
16.滑动窗口经典例题:最小覆盖子串(LeetCode 76)算法原理剖析
算法·leetcode·职场和发展
luj_176811 小时前
马克思的跨学科学术体系
c语言·开发语言·c++·经验分享·算法