字符串冲刺题(算法村第十二关黄金挑战)
最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""
。
示例 1:
输入:strs = ["flower","flow","flight"]
输出:"fl"
示例 2:
输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。
提示:
1 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i]
仅由小写英文字母组成
纵向扫描
public static String longestCommonPrefix(String[] strs)
{
if(strs.length == 0 || strs[0].isEmpty())
return "";
String firstStr = strs[0];
for (int i = 0; i < firstStr.length(); i++)
{
for(String curStr : strs)
if (i == curStr.length()
|| curStr.charAt(i) != firstStr.charAt(i))
return firstStr.substring(0, i);
}
return firstStr;
}
横向扫描
依次遍历字符串数组中的每个字符串,对于每个遍历到的字符串,更新最长公共前缀,当遍历完所有的字符串以后,即可得到字符串数组中的最长公共前缀。
如果在尚未遍历完所有的字符串时,最长公共前缀已经是空串,则最长公共前缀一定是空串,因此不需要继续遍历剩下的字符串,直接返回空串即可。
public String longestCommonPrefix(String[] strs)
{
if (strs.length == 0 || strs[0].isEmpty())
return "";
String prefix = strs[0];
for(String curStr : strs)
{
prefix = longestCommonPrefix_ofTwoStr(prefix, curStr);
if (prefix.equals(" "))
break;
}
return prefix;
}
public String longestCommonPrefix_ofTwoStr(String str1, String str2)
{
int index = 0;
int len = Math.min(str1.length(), str2.length());
while (index < len && str1.charAt(index) == str2.charAt(index))
index++;
return str1.substring(0, index);
}
压缩字符串
给你一个字符数组 chars
,请使用下述算法压缩:
从一个空字符串 s
开始。对于 chars
中的每组 连续重复字符 :
- 如果这一组长度为
1
,则将字符追加到s
中。 - 否则,需要向
s
追加字符,后跟这一组的长度。
压缩后得到的字符串 s
不应该直接返回 ,需要转储到字符数组 chars
中。需要注意的是,如果组长度为 10
或 10
以上,则在 chars
数组中会被拆分为多个字符。
请在 修改完输入数组后 ,返回该数组的新长度。
你必须设计并实现一个只使用常量额外空间的算法来解决此问题。
示例 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"]
解释:唯一的组是“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” 替代。
提示:
1 <= chars.length <= 2000
chars[i]
可以是小写英文字母、大写英文字母、数字或符号
空间复杂度 O(n)
public static int compress(char[] chars)
{
StringBuilder s = new StringBuilder();
//快慢双指针
int fast;
for (int slow = 0; slow < chars.length; slow = fast)
{
int count = 1;
//检查重复字符
for (fast = slow + 1; fast < chars.length; fast++)
{
if(chars[fast] == chars[slow])
count++;
else
break;
}
//压缩
s.append(chars[slow]);
if(count > 1)
s.append(count);
}
//修改chars
for (int i = 0; i < s.length(); i++)
chars[i] = s.charAt(i);
return s.length();
}
空间复杂度 O(1)
public static int compress_2(char[] chars)
{
if(chars.length == 1)
return 1;
int size = 0; //压缩后字符数组的有效长度
int count = 0; //重复字符数
for (int i = 0; i< chars.length; i++)
{
char curChar = chars[i]; //当前字符
count++;
//若当前字符是最后一个字符,或与下一个字符不同,则对当前字符进行压缩
if (i == chars.length - 1 || curChar != chars[i + 1])
{
chars[size] = curChar;
size++;
//压入数字
if (count > 1)
{
//计算 count 的位数
int tempCount = count;
int lengthOfCount = 0;
while (tempCount != 0)
{
lengthOfCount++;
tempCount /= 10;
}
//在 curChar 后压入数字。从个位开始,从右往左压入
int pos = size - 1 + lengthOfCount;
while (count > 0)
{
chars[pos--] = (char) ((count % 10) + '0');
count /= 10;
}
//更新压入数字后 chars 的有效长度
size += lengthOfCount;
}
//进行完一次压缩后便将 count 清零
count = 0;
}
}
return size;
}
原文地址:https://blog.csdn.net/cjj2543107638/article/details/135774395
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!