题目说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

示例 1:

输入: 121
输出: true
示例 2:

输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:

输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。
进阶:

你能不将整数转为字符串来解决这个问题吗?

解题思路一(字符串反转)

  1. 第一反应数字转字符串,然后前后对比。可以解决问题。

代码实现一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* @param {number} x
* @return {boolean}
*/
var isPalindrome = function(x) {
let xStr = x + '';
let mid = +(xStr.length >> 1) + (+xStr.length % 2);
for (let i = 0; i < mid; i++) {
if (xStr.charAt(i) != xStr.charAt(xStr.length - i - 1)) {
return false
}
}
return true;
};

解题思路二(求得x的位数,xLen = Math.log10(x))

  1. 求得长度,接下来跟字符串一样了。
  2. parseInt(x / Math.pow(10, xLen)) 得到首位
  3. x % 10 得到尾位
  4. 对比是否相等

代码实现二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* @param {number} x
* @return {boolean}
*/
var isPalindrome = function(x) {
if(x < 0) {
return false
}
let xLen = parseInt(Math.log10(x));
while(x >= 1) {
if(x % 10 != parseInt(x / Math.pow(10, xLen))) {
return false
}
x = x % Math.pow(10, xLen);
x = parseInt(x /= 10);
xLen-=2;
}
return true
};

解题思路三(反转尾部)

  1. 这个是官方题解,反转尾部,直到前半部分小于等于反转后的尾部
  2. 将x的尾部移出来,反转。一直到x剩下的前半部分等于或者小于反转的尾部。
  3. 前半部分小于尾部,说明到了x的中间位。
    1. 跳出循环时,回文数只有两种情况。
    2. 第一种,x为偶数,直接判断首尾是否相同。
    3. 第二种,x为奇数,尾部除以10,再进行判断。

代码实现三

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* @param {number} x
* @return {boolean}
*/
var isPalindrome = function(x) {
if(x < 0 || (x % 10 == 0 && x > 9)) {
return false
}
let xTail = 0;
let length = 0;
while(x > xTail) {
xTail *= 10;
xTail += x % 10;
x = parseInt(x / 10);
length++;
}
if (x == xTail || x == parseInt(xTail / 10)) {
return true
} else {
return false
}
};

题目说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。



示例 1:

输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"


提示:

0 <= num < 231

解题思路一(斐波那契数列)

  1. 我一般做题前喜欢先测试几个用例, 测试完发现这就是斐波那契数列
  2. 该题主要判断 i-1, i 两位组合成的数字是否在(10, 25)闭区间内. 如果在就是斐波那契f(n) = f(n-1) + f(n-2), 否则跟上一种情况一致f(n) = f(n-1).

代码实现一

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* @param {number} num
* @return {number}
*/
var translateNum = function(num) {
let numStr = num + '';
let res;
if (+(numStr[0] + numStr[1]) < 26 && +numStr[0] > 0) {
res = [1, 2];
} else {
res = [1, 1];
}
for(let i = 2; i < numStr.length; i++) {
if (+(numStr[i - 1] + numStr[i]) < 26 && +numStr[i - 1] > 0) {
res[i] = res[i - 1] + res[i - 2];
} else {
res[i] = res[i - 1];
}
}
return res[res.length-1]
};

半透明边框

背景知识:RGBA/HSLA 半透明颜色, 它们同样是一种颜色,并非只适用于背景。
background-clip 背景裁切属性,定义了背景的延伸范围,是否延伸到边框、内边距盒子、内容盒子,内容文字下面。分别对应border-box、padding-box、content-box、text四个属性值

Css

题目说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。



示例 1:

输入:matrix = [[1,2,3],[4,5,6],[7,8,9]]
输出:[1,2,3,6,9,8,7,4,5]
示例 2:

输入:matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
输出:[1,2,3,4,8,12,11,10,9,5,6,7]

限制:

0 <= matrix.length <= 100
0 <= matrix[i].length <= 100
注意:本题与主站 54 题相同:https://leetcode-cn.com/problems/spiral-matrix/

解题思路一(分层+递归)

  1. 首先明白题意,题目给出的示例数组是平铺的,不是特别清晰,可能短时间反应不过来它是想干嘛,我们先转换一下.
1
2
3
4
5
6
7
8
[
[1,2,3],
[4,5,6],
[7,8,9]
]
1 -> 2 -> 3 -> 6 -> 9 -> 8 -> 7 -> 4 -> 5

矩形外围开始,顺时针输出.
  1. 因为是从外层开始顺时针的,所以我们先看最外层的我们如何得到.
    1. 首先最外层相当于一个正方形的四条边.(我们将顶点放入上下两条边)
    2. top: [2], 加入左上和右上两个顶点为[1, 2, 3]
    3. right: [6]
    4. bottom: [8], 加入左下和右下两个顶点为 [7, 8, 9]
    5. left: [4]
    6. 结果[1,2,3,6,9,8,7,4,5] 其中left, bottom 需要反转过来.(因为顺时针)
  2. 剥离之后,原来的矩形只剩下了[[5]], 假若我们矩形是多层的, 那么剩下来的仍然是个矩形,那么我们就可以将剩下的矩阵重新传入, 重复上面第二步求出top right bottom left

    代码实现一

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    /**
    * @param {number[][]} matrix
    * @return {number[]}
    */
    var spiralOrder = function(matrix) {
    if (matrix.length <= 1) {
    return matrix[0] || [];
    }
    if (matrix[0].length <= 1) {
    return matrix.reduce(function(sum, item) {
    return [...sum, ...item];
    }, [])
    }
    let top = matrix.shift();
    let right = [], left = [];
    for (let i = 0; i < matrix.length; i++) {
    right.push(matrix[i].pop());
    left.unshift(matrix[i].shift());
    }
    let bottom = matrix.pop().reverse();
    let res = [...top, ...right, ...bottom, ...left];
    return res.concat(spiralOrder(matrix));
    };

题目说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14

给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。



示例:

输入: [1,2,3,4]
输出: [24,12,8,6]


提示:题目数据保证数组之中任意元素的全部前缀元素和后缀(甚至是整个数组)的乘积都在 32 位整数范围内。

说明: 请不要使用除法,且在 O(n) 时间复杂度内完成此题。

解题思路一(左右乘积列表)

  1. 如果可以用除法,那我们只需要求出列表乘积,然后除以nums[i]就是所求值了。
  2. 不用除法的情况下,我们需要求得nums[i]的左侧乘积L,和右侧乘积R,然后L*R求得目标值
  3. 那么我们创建两个乘积列表L,RL[i]代表从nums中从0 ~ i的乘积,R[i]代表nums中从i ~ nums.length - 1的乘积。
  4. 那么我们所求的output[i]就变成了L[I-1] * R[i+1];

    代码实现一

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    /**
    * @param {number[]} nums
    * @return {number[]}
    */
    var productExceptSelf = function(nums) {
    if (nums.length <= 2) {
    return nums.reverse();
    }
    let L = [nums[0]]
    let R = new Array(nums.length);
    R[nums.length-1] = nums[nums.length-1];
    for(let i = 1, j = nums.length - 2; i < nums.length; i++, j--) {
    L[i] = L[i-1] * nums[i];
    R[j] = R[j + 1] * nums[j];
    }
    for(let i = 1; i < nums.length - 1; i++) {
    nums[i] = L[i-1] * R[i + 1];
    }
    nums[0] = R[1];
    nums[nums.length-1] = L[nums.length-2];
    return nums;
    };

题目说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
给你一个数组 candies 和一个整数 extraCandies ,其中 candies[i] 代表第 i 个孩子拥有的糖果数目。

对每一个孩子,检查是否存在一种方案,将额外的 extraCandies 个糖果分配给孩子们之后,此孩子有 最多 的糖果。注意,允许有多个孩子同时拥有 最多 的糖果数目。



示例 1:

输入:candies = [2,3,5,1,3], extraCandies = 3
输出:[true,true,true,false,true]
解释:
孩子 1 有 2 个糖果,如果他得到所有额外的糖果(3个),那么他总共有 5 个糖果,他将成为拥有最多糖果的孩子。
孩子 2 有 3 个糖果,如果他得到至少 2 个额外糖果,那么他将成为拥有最多糖果的孩子。
孩子 3 有 5 个糖果,他已经是拥有最多糖果的孩子。
孩子 4 有 1 个糖果,即使他得到所有额外的糖果,他也只有 4 个糖果,无法成为拥有糖果最多的孩子。
孩子 5 有 3 个糖果,如果他得到至少 2 个额外糖果,那么他将成为拥有最多糖果的孩子。
示例 2:

输入:candies = [4,2,1,1,2], extraCandies = 1
输出:[true,false,false,false,false]
解释:只有 1 个额外糖果,所以不管额外糖果给谁,只有孩子 1 可以成为拥有糖果最多的孩子。
示例 3:

输入:candies = [12,1,12], extraCandies = 10
输出:[true,false,true]

解题思路一

  1. 这个题的话,理解好题意,很好回答。
  2. 题意转化后的意思就是,看candies中各项candies[i] + extraCandies 是否是candies中的最大值max
  3. 那么首先我们先找出来最大值,然后看其他各位加上extraCandies 之后能不能大于或者等于它,可以的话,该i位为true,否则为false。

    代码实现一

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /**
    * @param {number[]} candies
    * @param {number} extraCandies
    * @return {boolean[]}
    */
    var kidsWithCandies = function(candies, extraCandies) {
    let max = Math.max(...candies);
    return candies.map(item => {
    return (item + extraCandies >= max)
    })
    };

题目说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
给定一个整数数组 A,返回其中元素之和可被 K 整除的(连续、非空)子数组的数目。



示例:

输入:A = [4,5,0,-2,-3,1], K = 5
输出:7
解释:
有 7 个子数组满足其元素之和可被 K = 5 整除:
[4, 5, 0, -2, -3, 1], [5], [5, 0], [5, 0, -2, -3], [0], [0, -2, -3], [-2, -3]


提示:

1 <= A.length <= 30000
-10000 <= A[i] <= 10000
2 <= K <= 10000

题目说明

1
2
3
4
5
6
7
8
9
运用你所掌握的数据结构,设计和实现一个  LRU (最近最少使用) 缓存机制。它应该支持以下操作: 获取数据 get 和 写入数据 put 。

获取数据 get(key) - 如果关键字 (key) 存在于缓存中,则获取关键字的值(总是正数),否则返回 -1。
写入数据 put(key, value) - 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字/值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。


进阶:

你是否可以在 O(1) 时间复杂度内完成这两种操作?

题目说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。

示例 1:

输入: [1,3,4,2,2]
输出: 2
示例 2:

输入: [3,1,3,4,2]
输出: 3
说明:

不能更改原数组(假设数组是只读的)。
只能使用额外的 O(1) 的空间。
时间复杂度小于 O(n2) 。
数组中只有一个重复的数字,但它可能不止重复出现一次。