443. 压缩字符串
解法一、双指针
r只负责读,w只负责写
class Solution {
public static int compress(char[] chars) {
int r=0,w=0;
int len = chars.length;
while(r < len){
char c = chars[r];
int count = 1;
r++;
while(r < len && chars[r] == chars[r-1]){
count++;
r++;
}
String t = count + "";
chars[w] = c;
w++;
if(count !=1){
for(int i = 0;i < t.length();i++){
chars[w] = t.charAt(i);
w++;
}
}
}
return w;
}
}
解法二、也是双指针
只要read是最后一位或不等于下一位,则它是连续区段最后一位。
两种方法的差别:一个是读完一个连续段就开始从前写,一个是一个一个地读写。
对于{a,a,a,b,b,b,b,c,c,c},方法1写完是{a,3,b,4,c,3,b,c,c,c,c},方法2写完是{a,3,a,b,4,b,c,3,c}
class Solution {
public int compress(char[] chars) {
int n = chars.length;
int write = 0, left = 0;
for (int read = 0; read < n; read++) {
if (read == n - 1 || chars[read] != chars[read + 1]) {
chars[write++] = chars[read];
int num = read - left + 1;
if (num > 1) {
int anchor = write;
while (num > 0) {
chars[write++] = (char) (num % 10 + '0');
num /= 10;
}
reverse(chars, anchor, write - 1);
}
left = read + 1;
}
}
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--;
}
}
}
作者:力扣官方题解
链接:https://leetcode.cn/problems/string-compression/solutions/948556/ya-suo-zi-fu-chuan-by-leetcode-solution-kbuc/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
8. 字符串转换整数 (atoi)
解法一、模拟遍历
先讨论符号问题。'+'是43,‘-’是45,于是反减44 判断。while条件是该位是数字,不满足则跳出循环。while中的if讨论越界问题,如果讨论res * 10是不是超过MAX_VALUE,那么就讨论res和最大值/10的关系。若是前几位都大于,则直接返回;如果前几位都等于,最后一位大于7,也返回。
class Solution {
public static int myAtoi(String s) {
s = s.trim();
int op = 0;
int q = 0,res = 0,bndry = Integer.MAX_VALUE / 10;
int len = s.length();
if(len == 0)return 0;
if(s.charAt(q)=='-' || s.charAt(q) == '+'){
op = -(s.charAt(q) - 44);
q++;
}
while(q<len && s.charAt(q)<='9' && s.charAt(q)>= '0'){
if(res > bndry || res == bndry && s.charAt(q) > '7') return op > 0 ? Integer.MAX_VALUE :Integer.MIN_VALUE;
res = res * 10 + s.charAt(q) - '0';
q++;
}
return res;
}
}
class Solution {
public int romanToInt(String s) {
int len = s.length();
int sum = 0;
for(int i = 0;i < len;i++){
int num = change(s.charAt(i));
if(i != len-1 && num < change(s.charAt(i+1))){
sum -= num;
}else{
sum+=num;
}
}
return sum;
}
private int change(char c){
switch (c){
case 'I':
return 1;
case 'V':
return 5;
case 'X':
return 10;
case 'L':
return 50;
case 'C':
return 100;
case 'D':
return 500;
case 'M':
return 1000;
}
return 0;
}
}
13. 罗马数字转整数
解法一、模拟遍历
其实就是,若是比右面小则减,比右面大则加,最后一位肯定加,这样的规律。想出来的话代码就好写
class Solution {
public int romanToInt(String s) {
int len = s.length();
int sum = 0;
for(int i = 0;i < len;i++){
int num = change(s.charAt(i));
if(i != len-1 && num < change(s.charAt(i+1))){
sum -= num;
}else{
sum+=num;
}
}
return sum;
}
private int change(char c){
switch (c){
case 'I':
return 1;
case 'V':
return 5;
case 'X':
return 10;
case 'L':
return 50;
case 'C':
return 100;
case 'D':
return 500;
case 'M':
return 1000;
}
return 0;
}
}
碎碎念
- 学会了双指针遍历、讨论越界问题的逆向思维
- 最近几天做得最辛苦的一天,很难想象前两道题居然一道要花一小时,直接精准破防了。