- 3. Longest-Substring-Without-Repeating-Characters
- 4. Median-of-Two-Sorted-Arrays
- 5. longest-palindromic-substring
- 6. ZigZag-Conversion
- 11. Container-With-Most-Water.md
- 12. Integer-to-Roman.md
- 13. Roman-to-Integer.md
- 134. Gas-Station.md
- 14. Longest-Common-Prefix.md
- 15. 3sum.md
- 16. 3Sum-Closest.md
- 17. Letter-Combinations-of-a-Phone-Number.md
- 19. Remove-Nth-Node-From-End-of-List.md
- 20. Valid-Parentheses.md
- 21. Merge-Two-Sorted-Lists.md
- 22. Generate-Parentheses.md
- 6. ZigZag-Conversion.md
- 7. Reverse-Integer.md
- 9. Palindrome-Number.md
3. Longest-Substring-Without-Repeating-Characters
说明
最基本的思路是,遍历字符串,计算以每个字符开头的无重复子串长度,但是这样做的复杂度会很大,无法通过最后一个用例(这个题目的最后一个用例是用来测试算法的时间复杂度的)。
线性复杂度的算法思想描述如下:
遍历字符串,每次计算以当前字符结尾的最长不重复子串的length,遍历完成时,就得到了整个字符串的最长不重复子串。遍历时,将每个遇到的字符及其index以key:value形式存入一个hash中,我们每遇到一个字符,从hash中取寻找,判断之前是否遇见过,如果遇见过,那以当前字符结尾的最长不重复子串的开头字符的index的最小值就是最近一次遇到的这个字符的index。那么是不是说,最近一次遇到的这个字符的index就是开头了呢?不一定,因为我们要保证两个这两个相同的字符之间没有重复字符。如何保证这一点呢?这需要我们维护一个 名叫 start 的变量,每次发现一个字符之前遇到过,那就将start更新为 之前遇到的字符index。
代码
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
var hash = { };
var start = -1;
var max = 0;
var dis = 0;
for (var i = 0; i < s.length; i++) {
if (hash[s[i]] === undefined) {
dis = i - start;
}
else {
if (hash[s[i]] > start) {
dis = i - hash[s[i]];
start = hash[s[i]];
}
else {
dis = i - start;
}
}
hash[s[i]] = i;
max = (dis > max) ? dis : max;
}
return max;
};
4. Median-of-Two-Sorted-Arrays
说明:
先将两个数组归并,然后找出中间值
代码:
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @return {number}
*/
var findMedianSortedArrays = function(nums1, nums2) {
var arr = [];
var i = 0;
var j = 0;
var k = 0;
var mid;
while (i < nums1.length && j < nums2.length) {
if (nums1[i] < nums2[j]) {
arr.push(nums1[i++]);
}
else {
arr.push(nums2[j++]);
}
}
if (i < nums1.length) {
for (k = i; k < nums1.length; k++) {
arr.push(nums1[k]);
}
}
if (j < nums2.length) {
for (k = j; k < nums2.length; k++) {
arr.push(nums2[k]);
}
}
if (arr.length % 2 === 0) {
mid = (arr.length / 2) - 1;
return (arr[mid] + arr[mid + 1]) / 2;
}
else {
mid = (arr.length + 1) / 2 - 1;
return arr[mid];
}
};
5. longest-palindromic-substring
说明
最长回文串,考虑到长度为奇数的回文串和长度为偶数的回文串。
代码
var longestPalindrome = function(s) {
var max = 0;
var mark = {
i: 0,
j: 0
};
var result = '';
var getOddLength = function (s, index) {
var i = index;
var j = index;
while (i >= 0 && j < s.length) {
if (s[i] === s[j]) {
i--;
j++;
}
else {
break;
}
}
return j - i + 1;
};
var getEvenLength = function (s, index) {
if (index >= s.length ) {
return 0;
}
var i = index;
var j = index + 1;
while (i >= 0 && j < s.length) {
if (s[i] === s[j]) {
i--;
j++;
}
else {
break;
}
}
return j - i + 1;
};
var getResult = function (mark, s) {
var i = mark.i;
var j = mark.j;
var str = '';
while (i >= 0 && j < s.length) {
if (s[i] === s[j]) {
str = s[i] + str;
if (i !== j) {
str = str + s[j];
}
i--;
j++;
}
else {
break;
}
}
return str;
};
for (var i = 0; i < s.length; i++) {
var l1 = getOddLength(s, i);
var l2 = getEvenLength(s, i);
if (l1 > max) {
max = l1;
mark.i = i;
mark.j = i;
}
if (l2 > max) {
max = l2;
mark.i = i;
mark.j = i + 1;
}
}
return getResult(mark, s);
};
6. ZigZag-Conversion
说明:
首先要弄清zigzag模式的概念,在博客http://blog.csdn.net/zhouworld16/article/details/14121477中,有很清晰的介绍。
根据题意,可以知道,若要得到正确的结果,只需要将输入的字符串按照zigzag模式分配给给定数目(numRows)的数组,然后再讲每个字符串拼接起来即可。
代码:
/**
* @param {string} s
* @param {number} numRows
* @return {string}
*/
var convert = function(s, numRows) {
var result = '';
var arr = [ ];
var down = true;
var index = 0;
var row = 0;
var i;
// 创建长度为numRows的数组
for (i = 0; i < numRows; i++) {
arr.push('');
}
// 为数组分配字符
while (index < s.length) {
arr[row] += s[index];
if (down) {
if (row < numRows - 1) {
row++;
if (row === numRows - 1) {
down = false;
}
}
}
else {
if (row > 0) {
row--;
if (row === 0) {
down = true;
}
}
}
index ++;
}
// 将数组中的字符串拼接得到结果
for (i = 0; i < arr.length; i++) {
result += arr[i];
}
return result;
};
11. Container-With-Most-Water.md
说明:
题目是:给定n个非负整数 a1, a2..., ai..., an,表示在点(i, ai)处的点。现在根据这个整数序列画出n条线段,每个线段的两个端点分别为(i, 0)和(i, ai)。要求是从这n条线段中找出两条,使得这两条直线与x轴围成的容器所能容纳的水最多。
题目说是找出两条线段围成的容器中容纳水最多的那个,其实就是找出两条线段,使得(这两条线段之间的水平距离) * (两条线段中较短的那条) 值最大。
很容易想到的思路就是暴力穷举法,遍历每个点,计算 这个点对应的线段和其他所有线段围成的容器容量 中最大的值,记为maxi,求出最大的maxi,就是题目要求的结果。代码如下:
暴力穷举代码:
/**
* @param {number[]} height
* @return {number}
*/
var maxArea = function (height) {
// 计算两点围成的容器的容量
var getArea = function (i, j) {
var h = height[i] < height[j] ? height[i] : height[j];
return h * (j - i);
};
var max = 0;
// 遍历求解
for (var i = 0; i < height.length; i++) {
for (var j = i + 1; j < height.length; j ++) {
var area = getArea(i, j, height[i], height[j])
if (area > max) {
max = area;
}
}
}
return max;
};
很明显这个的复杂度是n^2。这个代码不能通过leetcode测试时间性能的测试用例。那么我们需要优化一下。如果我们希望能使一个算法的时间性能提升上去,即减少执行时间,可以从两个方面入手,第一是使用问题中的一些规则,减少算法的操作;第二是我们在算法过程中记录一些信息,在后续的执行过程中直接使用信息而不用再次计算。第二种思路的典型代表就是动态规划的思想。
我们这里使用第一种思路,规则就是:如果在点j处的线段是从点到点j之间的线段中最长的,那么,点i到点j之间的所有可能的容器中容量最大的就是点i处的线段和点j处的线段所围成的容器(原因是既然j处的线段是从i到j之间最长的,那么i到j之间的线段和i围成的容器的长和宽都不可能比j更大,因此j处的线段和i所围成容器一定是容量最大的)。根据这个规则,我们要记录两个信息:一个是正序 从下标为0到下标为i之间的线段中最长线段的下标,另一个是逆序 从下标为height.length -1 到下标为i之间的线段中最长的线段的下标。用这两个信息,当遍历到i时,如果i处的线段不是从0到i之间最大的,就可以不作任何操作(因为根据上面的规则,这时 i和其后任何线段围成的容器 都不会比 i之前那个比它长的线段和任何线段围成的容器的容量更大);而从i到其后最大的线段之间的容器容量也不必计算(因为它们和i围成的容器容量不会比i后最大的线段更大)。代码如下:
var maxArea = function (height) {
// 计算两点围成的容器的容量
var getArea = function (i, j) {
var h = height[i] < height[j] ? height[i] : height[j];
return h * (j - i);
};
var max;
var temp;
// 记录从0到i的最大height的下标
var preMax = [ ];
// 记录从heiht.length-1到i的最大height的下标
var postMax = [ ];
var i, j;
// temp在这里保存从0到i的最大height
temp = 0;
for (i = 0; i < height.length; i++) {
if (height[i] > temp) {
temp = height[i];
preMax.push(i);
}
else {
preMax.push(preMax[i - 1]);
}
}
// temp在这里保存从heiht.length-1的最大height
temp = 0;
for (i = height.length - 1; i >= 0; i--) {
if (height[i] > temp) {
temp = height[i];
postMax.unshift(i);
}
else {
postMax.unshift(postMax[0]);
}
}
max = 0;
// 遍历height数组,求容量最大值
for (i = 0; i < height.length; i++) {
if (preMax[i] === i) {
var area = getArea(i, postMax[i]);
if (max < area) {
max = area;
}
for (j = postMax[i] + 1; j < height.length; j++) {
area = getArea(i, j);
if (max < area) {
max = area;
}
}
}
}
return max;
};
这样就可以accept了。
12. Integer-to-Roman.md
说明:
该题目要求是将一个整数转换为一个罗马数字,所以首先要搞清楚罗马数字的规则。
罗马数字的规则:
罗马数字和阿拉伯数字一样,都是十进制的,所以我们只要把每一位的数字拼凑到一起就可以了。但是有一点需要注意的是,罗马数字不同于阿拉伯数字,它的每一位数字表示方法不同,比如,对于阿拉伯数字,五用 ‘5’来表示,而五十只需要把 '5'放在十位就行了:‘50’,因为有0占位,因此不会有任何歧义。但是罗马数字没有占位机制,因此各个位的表示方法不同,如五用罗马数字表示为 ‘V’,五十则为 ‘X’。
虽然罗马数字每一个位对应的数字符号不同,但是表示的方法都是一样的,都是通过表示‘1’的符号和表示‘5’的符号组合而成。表示方法如下:假设某一位表示‘1’的符号为A,表示‘5’的符号为B,则 0,1,2,3,4,5,6,7,8,9分别为 ‘’(空字符),A, AA, AAA, AB(可以这么理解,A位于B左侧相当于B-A,A位于B右侧相当于B+A), B, BA, BAA, BAAA, AC(C是更高一位的‘1’,相当于10 - 1)。
根据上面的叙述,我们只需要知道每一位表示 ‘1’和 ‘5’的符号,就可以按照上述规则拼凑起罗马数字了。
值得注意的是,题目中说明输入整数从1 ~ 3999 ,因此只需要知道个位到千位的表示符号即可。
代码:
/**
* @param {number} num
* @return {string}
*/
var intToRoman = function(num) {
var result = '';
var temp;
var list = [
{
one: 'I',
five: 'V'
},
{
one: 'X',
five: 'L'
},
{
one: 'C',
five: 'D'
},
{
one: 'M'
}
];
var map = function (integer, cur, next) {
var one = cur.one;
var five = cur.five;
var ten = next && next.one;
switch (integer) {
case 0:
return '';
case 1:
return one;
case 2:
return one + one;
case 3:
return one + one + one;
case 4:
return one + five;
case 5:
return five;
case 6:
return five + one;
case 7:
return five + one + one;
case 8:
return five + one + one + one;
case 9:
return one + ten;
}
};
while (num) {
temp = num % 10;
result = map(temp, list[0], list[1]) + result;
list.shift();
num = Math.floor(num / 10);
}
return result;
};
13. Roman-to-Integer.md
说明:
题目要求将罗马数字转为阿拉伯数字。思路是从个位开始,匹配各个位的数字,一直到最高位为止。需要注意两点,第一是要移除已经匹配完的数字,防止在匹配更高位数字时产生歧义。第二是在匹配的时候,为防止歧义,应遵循一定顺序,比如应先匹配4,6,7,8然后再匹配5。
代码:
/**
* @param {string} s
* @return {number}
*/
var romanToInt = function(s) {
var num = 0;
var list = [
{
grade: 1,
one: 'I',
five: 'V'
},
{
grade: 10,
one: 'X',
five: 'L'
},
{
grade: 100,
one: 'C',
five: 'D'
},
{
grade: 1000,
one: 'M'
}
];
var map = function (cur, next) {
var result = 0;
var one = cur.one;
var five = cur.five;
var ten = next && next.one;
var nine = ten ? (one + ten) : 'doomliu';
var fiveIndex = s.indexOf(five);
var oneIndex = s.indexOf(one);
var nineIndex = s.indexOf(nine);
if (nineIndex !== -1) {
s = s.slice(0, nineIndex);
result = 9;
}
else if (fiveIndex !== -1) {
var preIndex = postIndex = fiveIndex;
while (preIndex >= 0 && (s[--preIndex] === one)) { }
while (postIndex <= s.length - 1 && (s[++postIndex] === one)) { }
s = s.slice(0, preIndex + 1);
result = 5 + ((postIndex - 1) + (preIndex + 1) - 2 * fiveIndex);
}
else if (oneIndex !== -1) {
var postIndex = oneIndex;
while (postIndex <= s.length - 1 && s[++postIndex] === one) { }
s = s.slice(0, oneIndex);
result = (postIndex - 1) - oneIndex + 1;
}
result *= cur.grade;
return result;
};
while (list.length) {
num += map(list[0], list[1]);
list.shift();
}
return num;
};
134. Gas-Station.md
代码
/**
* @param {number[]} gas
* @param {number[]} cost
* @return {number}
*/
var canCompleteCircuit = function(gas, cost) {
var arr = [];
var curSum = 0;
var positiveSum = 0;
var positiveIndex = 0;
var index = gas.length - 1;
gas.forEach((item, index) => {
arr.push(item - cost[index])
});
while (index >= 0) {
if (arr[index] < 0) {
curSum = arr[index--];
while (curSum < 0 && index >= 0) {
curSum += arr[index--];
}
if (index < 0) {
if (curSum + positiveSum >= 0) {
return positiveIndex
}
else {
return -1
}
}
else {
positiveSum += curSum;
positiveIndex = index + 1;
curSum = 0;
}
}
else {
while (arr[index] >= 0 && index >= 0) {
positiveSum += arr[index];
positiveIndex = index--;
}
if (index < 0) {
return 0
}
}
}
return -1
};
14. Longest-Common-Prefix.md
说明:
题目要求找出一个字符串数组中的所有字符串的最长前缀。
代码:
/**
* @param {string[]} strs
* @return {string}
*/
var longestCommonPrefix = function (strs) {
var result = '';
var breakFlag = false;
var curStr = '';
var i = j = 0;
if (!strs.length) {
return result;
}
while (true) {
if (i > strs[0].length - 1) {
break;
}
curStr = strs[0][i];
for (j = 0; j < strs.length; j++) {
if (strs[j][i] !== curStr || i > strs[j].length - 1) {
breakFlag = true;
break;
}
else if (j === strs.length - 1) {
result += strs[j][i];
}
}
if (breakFlag) {
break;
}
i++;
}
return result;
};
15. 3sum.md
说明
题目是,给定一个数组(nums),返回一个数组(假定为result),result的每个元素都是一个数组(假定为ele),ele长度为3,其中的3个元素不重复地取自nums,并且这3个元素之和为0。result中的各数组要保证3元素组合不重复。
首先最容易想到的方法是暴力遍历,用一个3重循环求取结果,再去重即可。这样复杂度为n^3。
可以从多个角度进行优化
第一,先把输入参数nums升序排序,这样可以在遍历的过程中判断两数之和是否大于0,如果大于0可以不用再向后遍历,这就减少了一定的计算量;
第二,可以给nums去重,保证每个元素最多只有3个重复;
第三,可以先把nums中每个元素存到一个hash里,key就是这个元素的值,value是这个元素最后出现的下标,遍历的时候,只需要两重遍历即可;
代码
/**
* @param {number[]} nums
* @return {number[][]}
*/
var threeSum = function(nums) {
var resultHash = {};
var numsHash = {};
var result = [];
var newNums = [];
var newNumsHash = {};
// nums去重
nums.forEach(function (item, index) {
if (newNumsHash[item] !== 3) {
newNums.push(item);
if (newNumsHash[item]) {
newNumsHash[item]++;
}
else {
newNumsHash[item] = 1;
}
}
});
// 排序
var list = newNums.sort(function (a, b) {
return a - b;
});
// 将nums转成hash
for (var i = 0; i < list.length; i++) {
numsHash[list[i]] = i + 1;
}
// 两重遍历确定两个数,第三个数在numsHash里找
for (var j = 0; j < list.length; j++) {
for (var k = j + 1; k < list.length; k++) {
var target = -(list[j] + list[k]);
// 因为数组是升序排好序的,所以如果两数之和大于0,再加上后面的肯定不为0
if (target < 0) {
break;
}
if (numsHash[target]
&& (numsHash[target] - 1) !== j
&& (numsHash[target] - 1) !== k
) {
var arr = [list[j], list[k], target];
var resultHashKey = arr.sort().join('_');
if (!resultHash[resultHashKey]) {
result.push(arr);
resultHash[resultHashKey] = true;
}
}
}
}
return result;
};
16. 3Sum-Closest.md
说明
题目是,给定一个数组,和一个目标值,找出数组中的3个数,这3个数之和离目标值最近。
可以直接想出的方法就是三重循环遍历。为了减少计算,需要先对数组进行排序,然后根据遍历中当前3个元素之和与目标值的关系判定是否需要继续向后遍历。
代码
/**
* @param {number[]} nums
* @param {number} target
* @return {number}
*/
var threeSumClosest = function(nums, target) {
var list = nums.sort(function (a, b) {
return a - b;
});
var distance = Math.abs((list[0] + list[1] + list[2]) - target);
var tempSum;
for (var i = 0; i < list.length; i++) {
for (var j = i + 1; j < list.length; j++) {
for (var k = j + 1; k < list.length; k++) {
if (Math.abs(list[i] + list[j] + list[k] - target) > distance) {
if ((list[i] + list[j] + list[k] - target) > 0) {
break;
}
}
else {
distance = Math.abs(list[i] + list[j] + list[k] - target);
tempSum = list[i] + list[j] + list[k];
}
}
}
}
return tempSum;
};
17. Letter-Combinations-of-a-Phone-Number.md
说明
当我们使用手机的9键键盘时,每个按键对应多个字母,我们按下几个键后,对应多种可能的字母组合。题目要求根据输入的数字求出所有可能的字母组合。这个题就是简单的递归题目,和字符全排列类似。
代码
/**
* @param {string} digits
* @return {string[]}
*/
var letterCombinations = function(digits) {
const map = {
'2': ['a', 'b', 'c'],
'3': ['d', 'e', 'f'],
'4': ['g', 'h', 'i'],
'5': ['j', 'k', 'l'],
'6': ['m', 'n', 'o'],
'7': ['p', 'q', 'r', 's'],
'8': ['t', 'u', 'v'],
'9': ['w', 'x', 'y', 'z']
};
var result = [];
const it = (prefix, seq, result) => {
if (seq.length === 0) {
return;
}
else if (seq.length === 1) {
map[seq[0]].forEach((item, index) => {
result.push(prefix + item);
});
return;
}
else {
map[seq[0]].forEach((item, index) => {
it(prefix + item, seq.slice(1), result);
});
}
}
it('', digits, result);
return result;
};
19. Remove-Nth-Node-From-End-of-List.md
说明
题目要求删除链表倒数第n个节点。
这是个典型的双指针问题,先让前指针走n步,然后两个指针一起走,直到前指针走到链表末尾,最后删掉后指针指向的节点即可。
值得注意的是,这里的头指针不是一个指向第一个节点的节点,它就是第一个节点。
代码
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @param {number} n
* @return {ListNode}
*/
var removeNthFromEnd = function(head, n) {
var h = new ListNode(0);
h.next = head;
var i = h, j = h;
for (var k = 0; k < n; k++) {
j = j.next;
}
while (j.next) {
i = i.next;
j = j.next;
}
i.next = i.next.next;
return h.next;
};
20. Valid-Parentheses.md
说明
题目要求判断一个括号序列是否合法。
这是一个典型的栈问题。
代码
/**
* @param {string} s
* @return {boolean}
*/
var isValid = function(s) {
var stack = [];
var match = {
')': '(',
']': '[',
'}': '{',
};
for (var i = 0; i < s.length; i++) {
if (stack.length > 0 && match[s[i]] === stack[stack.length - 1]) {
stack.pop();
}
else {
stack.push(s[i]);
}
}
if (stack.length === 0) {
return true;
}
return false
};
21. Merge-Two-Sorted-Lists.md
说明
合并两个列表,这里list使用的是链表结构
代码
// Definition for singly-linked list.
function ListNode(val) {
this.val = val;
this.next = null;
}
/**
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
var mergeTwoLists = function(l1, l2) {
var i = l1;
var j = l2;
var h1 = h2 = new ListNode();
while (i && j) {
if (i.val < j.val) {
h2.next = i;
h2 = h2.next;
i = i.next;
}
else {
h2.next = j;
h2 = h2.next;
j = j.next;
}
}
if (i) {
while (i) {
h2.next = i;
h2 = h2.next;
i = i.next;
}
}
if (j) {
while (j) {
h2.next = j;
h2 = h2.next;
j = j.next;
}
}
return h1.next;
};
22. Generate-Parentheses.md
说明:
题目要求找出n个括号所能组成的所有合法括号序列,所谓合法括号序列,指的是从左到右遍历序列,任意位置都满足,左括号的个数大于等于右括号的个数。
代码:
/**
* @param {number} n
* @return {string[]}
*/
var generateParenthesis = function(n) {
var stack = [];
var result = [];
var curLeft = 0;
var curRight = 0;
function getEnd(n) {
var result = ''
for (var i = 0; i < n; i++) {
result += '()';
}
return result;
}
var end = getEnd(n);
function reachEnd() {
return stack.join('') == end;
}
function init() {
for (var i = 0; i < n; i++) {
stack.push('(')
}
for (var i = 0; i < n; i++) {
stack.push(')')
}
result.push(stack.join(''));
}
init();
while (!reachEnd()) {
// 出栈
while (true) {
var ele = stack.pop();
if (ele == '(') {
curLeft++
if (curLeft < curRight) {
break;
}
}
else {
curRight++
}
}
// 入栈
while (curRight) {
stack.push(')');
curRight--;
while (curLeft) {
stack.push('(')
curLeft--
}
while (curRight) {
stack.push(')')
curRight--
}
}
result.push(stack.join(''))
}
return result
};
6. ZigZag-Conversion.md
说明:
首先要弄清zigzag模式的概念,在博客http://blog.csdn.net/zhouworld16/article/details/14121477中,有很清晰的介绍。
根据题意,可以知道,若要得到正确的结果,只需要将输入的字符串按照zigzag模式分配给给定数目(numRows)的数组,然后再讲每个字符串拼接起来即可。
代码:
/**
* @param {string} s
* @param {number} numRows
* @return {string}
*/
var convert = function(s, numRows) {
var result = '';
var arr = [ ];
var down = true;
var index = 0;
var row = 0;
var i;
// 创建长度为numRows的数组
for (i = 0; i < numRows; i++) {
arr.push('');
}
// 为数组分配字符
while (index < s.length) {
arr[row] += s[index];
if (down) {
if (row < numRows - 1) {
row++;
if (row === numRows - 1) {
down = false;
}
}
}
else {
if (row > 0) {
row--;
if (row === 0) {
down = true;
}
}
}
index ++;
}
// 将数组中的字符串拼接得到结果
for (i = 0; i < arr.length; i++) {
result += arr[i];
}
return result;
};
7. Reverse-Integer.md
说明:
32位有符号整数的范围就是-2^31 ~ 2^31。
该题目有个细节要注意,就是不仅输入的数32位溢出时要返回0。而且翻转后的数32位溢出时也要返回0。
代码:
/**
* @param {number} x
* @return {number}
*/
var reverse = function(x) {
var result = 0;
if (Math.abs(x) >= 2147483648) {
result = 0;
}
else {
if (x >= 0) {
result = +(('' + x).split('').reverse().join(''));
}
else {
result = -(('' + -x).split('').reverse().join(''))
}
}
if (Math.abs(result) >= 2147483648) {
result = 0;
}
return result;
};
9. Palindrome-Number.md
说明
判断一个数字是否具有回文特性,不允许使用额外存储空间
思路是,先将改数转换为一个字符串,然后一次比较头尾两个字符是否相等,然后掐头去尾。如果一直相等直到只剩下0个字符或者1个字符,那么可以断定改数为回文数
代码
var isPalindrome = function(x) {
x = '' + x;
while (x !== '') {
if (x[0] === x[x.length - 1] && x.length >= 2) {
x = x.slice(1, x.length - 1).slice(0, x.length - 2);
}
else {
break;
}
}
if (x.length <= 1) {
return true;
}
return false;
};