目录
题目
思路
Code
题目
题目内容:
给定一个只包含大小写英文字母的字符串,请实现字符串压缩编码功能。
压缩规则如下:
如果字符连续出现次数大于 1,则用字符加上出现次数表示。
如果字符连续出现次数等于 1,则直接输出字符。
输入描述:
输入一行,包含一个字符串 str,长度范围为 1 到 1000。
字符串只包含大小写英文字母。
输出描述:
输出压缩后的字符串。
样例 1
输入:
aabcccccaaa输出:
a2bc5a3说明:
aa 压缩为 a2,b 单个字符直接输出,ccccc 压缩为 c5,aaa 压缩为 a3。
样例 2
输入:
b输出:
b说明:
单个字符直接输出。
样例 3
输入:
AAbB输出:
A2bB说明:
大小写敏感,AA 压缩为 A2,b 和 B 分别直接输出。
思路
从左到右扫描字符串,使用两个位置标记当前连续字符段的起点和终点。
每次找到一段连续相同字符后,根据这段长度决定输出字符本身,还是输出字符加次数。
扫描过程中每个字符只会被归入一个连续段,因此整体时间复杂度为线性,结果字符串按段追加即可。
Code
import java.util.*; public class Main { static String compress(String s) { // StringBuilder 按段追加,避免长字符串场景下频繁创建中间对象。 StringBuilder ans = new StringBuilder(); int i = 0; while (i < s.length()) { int j = i; // 找到当前连续字符段的右边界,一次性统计该段长度。 while (j < s.length() && s.charAt(j) == s.charAt(i)) { j++; } int count = j - i; ans.append(s.charAt(i)); // 单个字符不写 1,避免把原本无需压缩的字符变长。 if (count > 1) { ans.append(count); } i = j; // 跳到下一段起点继续处理。 } // 每个连续段都已经按原始顺序输出,直接返回拼接结果。 return ans.toString(); } public static void main(String[] args) { Scanner sc = new Scanner(System.in); // 题目输入只有一行,trim 只用于去掉行尾换行或多余空白。 String s = sc.hasNextLine() ? sc.nextLine().trim() : ""; System.out.println(compress(s)); } }Go
package main import ( "bufio" "fmt" "os" "strconv" "strings" ) func compress(s string) string { var ans strings.Builder for i := 0; i < len(s); { j := i // 统计当前字符连续段的长度。 for j < len(s) && s[j] == s[i] { j++ } count := j - i ans.WriteByte(s[i]) // 只有重复字符段才写入次数,单个字符保持原样。 if count > 1 { // Itoa 保留完整次数,支持 10、1000 这类多位计数。 ans.WriteString(strconv.Itoa(count)) } i = j // 跳到下一段,避免重复扫描已经处理过的字符。 } // Builder 中已经按连续段顺序写入所有输出片段。 return ans.String() } func main() { reader := bufio.NewReader(os.Stdin) s, _ := reader.ReadString('\n') // 输入只有一行字母串,去掉行尾换行后再压缩。 s = strings.TrimSpace(s) fmt.Println(compress(s)) }C
#include <stdio.h> #include <string.h> int main() { char s[1005]; if (scanf("%1000s", s) != 1) { return 0; } int n = strlen(s); int i = 0; while (i < n) { int j = i; // 找到当前连续字符段的结束位置。 while (j < n && s[j] == s[i]) { j++; } int count = j - i; putchar(s[i]); // 连续出现超过一次才输出次数,单个字符不输出 1。 if (count > 1) { // printf 可以直接输出多位次数,不需要手动拆数字。 printf("%d", count); } i = j; // 继续处理下一段连续字符。 } // 统一补换行,方便和测试输出逐字节比对。 putchar('\n'); return 0; }【华为od机试真题Python+JS+Java+Go合集】【超值优惠】:Py/JS/Java/Go合集
【华为od机试真题Python】:Python真题题库
【华为od机试真题JavaScript】:JavaScript真题题库
【华为od机试真题Java&Go】:Java&Go真题题库
【华为od机试真题C++】:C++真题题库
【华为od机试真题C语言】:C语言真题题库
【华为od面试手撕代码题库】:面试手撕代码题库
【华为od机试面试交流群】【文章底部有二维码链接,可扫码加交流群】
华为OD机试:二本院校有机会吗? 有机会,但不大,大神除外!机考分数越高越好,所以需要提前刷题。机考通过后,如果没有收到面试邀请,也不要着急,非目标院校面试邀请发的时间比较晚。非目标院校今年有点难,机试至少要考到350分,所以需要疯狂刷题,华为OD机考是有题库的,最好在考前完所有题库题目。华为OD机试:跨专业可以参加华为OD可以,但是如果你的本科院校比较差,上岸概率不大。华为OD机试:华为OD简历被锁定机试通过,性格测试也通过,但是没人联系面试,发现简历被锁定。此时需要主动去联系HR。让他帮助你查询原因。