目录
151. 翻转字符串里的单词(middle) ——04/10
7. 整数反转(easy)—03/07
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123
输出: 321
示例 2:输入: -123
输出: -321
示例 3:输入: 120
输出: 21
注意:假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
解题思路:
用js做比较简单,因为数组提供reverse方法,直接reverse一下,然后拼回去就行了。
注意:
要判断边界。
而且字符串转数字的时候,+"00023" -> 23 ,可以不处理前面的0
/**
* @param {number} x
* @return {number}
*/
var reverse = function(x) {
str = Math.abs(x) + '';
num = str.split('').reverse().join('');
num = (x >= 0) ? num : -num;
if(num <= Math.pow(-2,31) || num >= Math.pow(2,31) - 1 ){
return 0;
}
return num
};
13. 罗马数字转整数(easy)—03/06
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。
解题思路:
将字母和数字做映射,遍历字符串。
当前数字比后一个数字大时,可以直接加上,当前数字比后一个数字小时,需要减去。
注意:
需要判断边界条件,即当前i是最后一个的时候,直接加上,不对比i+1了。
越界时,即访问arr[len]及之后的数字时,js不会报错,都是undefined。
undefined与数值比较时,会强制转换为NaN,与数值进行比较时返回都是false
undefined>1 -> false ; undefined<1 -> false;会走到else中。
1.使用Map,牺牲了空间,但时间很快
/**
* @param {string} s
* @return {number}
*/
var romanToInt = function(s) {
let map = new Map([['I',1],['V',5],['X',10],['L',50],['C',100],['D',500],['M',1000]]);
arr = s.split('');
let sum=0;
for(let i=0;i<arr.length;i++){
if (i === arr.length-1) {
sum+=map.get(arr[i]);
break;
}
if(map.get(arr[i]) >= map.get(arr[i+1])){
sum+=map.get(arr[i])
} else {
sum-=map.get(arr[i])
}
}
return sum;
};
2.使用Obj,空间比较小,时间慢了
/**
* @param {string} s
* @return {number}
*/
var romanToInt = function(s) {
let obj = {
'I':1,
'V':5,
'X':10,
'L':50,
'C':100,
'D':500,
'M':1000
}
arr = s.split('');
let sum=0;
for(let i=0;i<arr.length;i++){
if (i === arr.length-1) {
sum+=obj[arr[i]];
break;
}
if(obj[arr[i]] >= obj[arr[i+1]]){
sum+=obj[arr[i]]
} else {
sum-=obj[arr[i]]
}
}
return sum;
};
125. 验证回文串(easy)—03/07
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
示例 1:
输入: "A man, a plan, a canal: Panama"
输出: true
示例 2:输入: "race a car"
输出: false
解题思路:
只考虑字母和数字字符 ——> 代表 要过滤掉除了字母和数字的所有字符
1.可以使用首尾指针来比较实现
2.可以直接reverse来对比
注意:
过滤可以直接使用正则表达式![^0-9a-zA-Z] 这样就能过滤掉所有其他字符
也可以使用ASCII编码 (s>='0' &&s<='9') || (s>='a'&&s<='z')
/**
* @param {string} s
* @return {boolean}
*/
var isPalindrome = function(s) {
s = s.toLowerCase().replace(/[^0-9|a-z]/g,'');
reverse = s.split('').reverse().join('');
if (reverse === s){
return true;
}
return false;
};
面试题 01.06. 字符串压缩(easy)——03/27
字符串压缩。利用字符重复出现的次数,编写一种方法,实现基本的字符串压缩功能。比如,字符串aabcccccaaa会变为a2b1c5a3。若“压缩”后的字符串没有变短,则返回原先的字符串。你可以假设字符串中只包含大小写英文字母(a至z)。
示例1:
输入:"aabcccccaaa"
输出:"a2b1c5a3"
示例2:输入:"abbccd"
输出:"abbccd"
解释:"abbccd"压缩后为"a1b2c2d1",比原字符串长度更长。
解题思路:
1.暴力解法:遍历字符串
2.正则表达式:分组匹配
1.遍历字符串
/**
* @param {string} S
* @return {string}
*/
var compressString = function(S) {
let count=1;
let str = '';
let char = S[0];
for(let i = 1 ; i < S.length+1 ; i++){
if(S[i-1] === S[i]){
count++
}else{
str += char+ count
count = 1
char = S[i]
}
}
return S.length > str.length ? str : S
};
2.正则匹配
var compressString = function(S) {
let res = ''
let sReg = S.match(/([A-z])\1*/g)
if(sReg){
sReg.forEach(e=>{
res += e.charAt(0)+e.length
})
}
return res.length < S.length ? res : S
};
17. 电话号码的字母组合(middle)——03/28
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。
示例:
输入:"23"
输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
解题思路:
递归,递归出口是匹配完成。
用map来存储匹配规则
/**
* @param {string} digits
* @return {string[]}
*/
var letterCombinations = function(digits) {
const map = new Map([['2','abc'],['3','def'],['4','ghi'],['5','jkl'],['6','mno'],['7','pqrs'],['8','tuv'],['9','wxyz']]);
let res = [];
if (digits==null || digits.trim() == ''){
return res;
}
function letterCom(str,index){
if (index === digits.length){
res.push(str);
return ;
}
let tmp = [...map.get(digits.charAt(index))];
tmp.forEach(item=>{letterCom(str+item,index+1)})
}
letterCom('',0);
return res;
};
151. 翻转字符串里的单词(middle) ——04/10
给定一个字符串,逐个翻转字符串中的每个单词。
示例 1:
输入: "the sky is blue"
输出: "blue is sky the"
示例 2:输入: " hello world! "
输出: "world! hello"
解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
示例 3:输入: "a good example"
输出: "example good a"
解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
说明:
无空格字符构成一个单词。
输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。
解题思路:(无情的API使用者)
1.把多个空格减少为一个空格 —— 正则表达式 /\s+/ig
/**
* @param {string} s
* @return {string}
*/
var reverseWords = function(s) {
return s.trim().replace(/\s+/ig,' ').split(' ').reverse().join(' ');
};