翻转句子里的单词

问题描述

现在有一个小任务,假设有一个字符串 “I love coding”,要求将里面单词的顺序翻转,但是单词内部的字母顺序不变,也就是翻转之后结果为 “coding love I“。

求解思路

  • 将字符串分割成若干个子串。

  • 利用中心对称,将字符串转换成为倒序的。

  • 遍历子串,去掉多余的空格,每个有效的子串后面增加一个空格。

  • 去掉结果最后多余的空格。

代码实现

const reverseWords = s => {
const arr = s.split(' ');
const res = [];
for (let i = arr.length - 1; i >= 0; i--) {
arr[i] && res.push(arr[i]);
}
return res.join(' ');
};

寻找最长回文子串

问题描述

“上海自来水来自海上”,这句话不管是顺着读还是逆着读,都是一样的,这就是回文串。给出一个字符串 s,找到 s 里面包含的最长的回文串

例子

输入:s = abddbc
输出:bd

求解思路

我们知道回文串是顺序或者逆序,都是一样的,那么就说明回文串都有一个中心,也就是对称轴,比如 abba,对称轴是两个 b 字符之间。 abcba 的对称轴则是 c。也就是以下规律:

  • 字符数为奇数的回文串的中心是一个字符。
  • 字符数为偶数的回文串的中心是两个字符的间隙。

怎么能兼容两种 case 呢?我们可以设计一个方法,传入两个索引参数,如果两个参数相同,中心往两边拓展的时候,拓展出来的字符数是奇数。如果两个索引参数是相邻的两个数,那么拓展出来的字符数就是偶数。

代码实现

/**
* @param {string} s
* @return {number}
*/
var longestPalindrome = function (s) {
// 思路:从中间开始向两边扩散来判断回文串
let palindrome = (s, l, r) => {
while (l >= 0 && r < s.length && s[l] == s[r]) {
// 向两边展开
l--;
r++;
}
// 返回以s[l]和s[r]为中心的最长回文串
return s.slice(l+1, r);
};
let res = "";
for (let i = 0; i < s.length; i++) {
// 中心为 i 的奇数个回文串
let s1 = palindrome(s, i, i);
// 中心为 i 和 i+1 的偶数个回文串
let s2 = palindrome(s, i, i + 1);
res = res.length > s1.length ? res : s1;
res = res.length > s2.length ? res : s2;
}
return res;
};

字符串转整数

问题描述

偶尔我们会遇到一些情况,输入一个字符串,要转换成为一个整数,现在有一个小任务,需要我们将字符串转换成为 32 位的有符号的整数,当然有一些小的规则:

  • 如果字符串的前面有空格,那么可以忽略
  • 符号只能存在于数字前面,也就是类似“+3”,“-2”,而 “2-1” 则是只能读取到 2,后面不规则的需要忽略。
  • 如果超过了 32 位有符号整数的范围,需要将其截断,大于 2^31-1 则返回 2^31-1,小于 -2^31 则返回 -2^31

解题思路

去掉首尾空格之后,如果第一个符号为-,则表示负号
如果第一个符号为+,则表示正数,当然+是可选的
遍历去掉首尾空格后的字符串,如果当前字符是数字,则累加(累加的时候判断是否溢出,如果溢出则直接按照题意返回就行了),否则就可以直接退出了

代码实现

/**
* @param {string} str
* @return {number}
*/
var strToInt = function (str) {
let res = 0,
// 正负号,默认正号
negativeSymbol = 1;
// 把首尾的空格都去掉
str = str.trim();
for (let i = 0; i < str.length; i++) {
// 负数
if (i == 0 && str[i] == "-") {
negativeSymbol = -1;
continue;
// 正数
} else if (i == 0 && str[i] == "+") continue;
// 因为空格会被转成0,所以要排除空格的情况,也就是说在数字范围内就加上
if (str[i] >= 0 && str[i] <= 9 && str[i] != " ") {
res = res * 10 + (str[i] - 0);
// 为什么在这里就判断呢,因为这里如果就溢出的话,就提前退出,不需要再后面无意义的计算了
if (res * negativeSymbol <= -2147483648) return -2147483648;
else if (res * negativeSymbol >= 2147483647) return 2147483647;
} else break;
}
return res * negativeSymbol;
};