每日LeetCode
数组
1. 移除元素(简单)
题目描述:
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:
给定 nums = [3,2,2,3], val = 3,
函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。
你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,1,2,2,3,0,4,2], val = 2,
函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
注意这五个元素可为任意顺序。
你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);
// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
解题思路:
p
,q
指针,p
从头开始,q
从后开始,如果nums[p]
等于val
且nums[q]
不等于val
,则与nums[q]
交换位置,返回的p
就是剩下的数组长度。
解题代码:
class Solution {
public int removeElement(int[] nums, int val) {
int p = 0, q = nums.length - 1;
while (p <= q) {
if (nums[p] != val) {
p++;
} else {
if (nums[q] != val) {
int tmp = nums[q];
nums[q] = nums[p];
nums[p] = tmp;
p++;
} else {
q--;
}
}
}
return p;
}
}
数学
1. 整数反转(简单)
题目描述:
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例1:
输入: 123
输出: 321
示例2:
输入: -123
输出: -321
示例3:
输入: 120
输出: 21
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
解题思路1:
将整数x
用long
类型接收(原因是如果输入x
为-2^31
,无法对x
取绝对值),然后取绝对值翻转,然后判断是否溢出,返回结果。
解题代码1:
class Solution {
public int reverse(int x) {
long in = x;
String s = String.valueOf(Math.abs(in));
String resStr = new StringBuilder(s).reverse().toString();
if (Long.parseLong(resStr) > Integer.MAX_VALUE) {
return 0;
}
if (in < 0) {
return (-Integer.parseInt(resStr));
}
return Integer.parseInt(resStr);
}
}
解题思路2:
- 通过循环将数字
x
的每一位拆开,在计算新值时每一步都判断是否溢出。 - 溢出条件有两个,一个是大于整数最大值
MAX_VALUE
,另一个是小于整数最小值MIN_VALUE
,设当前计算结果为ans
,下一位为pop
。 - 从
ans * 10 + pop > MAX_VALUE
这个溢出条件来看
当出现ans > MAX_VALUE / 10
且 还有pop
需要添加 时,则一定溢出
当出现ans == MAX_VALUE / 10
且pop > 7
时,则一定溢出,7
是2^31 - 1
的个位数 - 从
ans * 10 + pop < MIN_VALUE
这个溢出条件来看
当出现ans < MIN_VALUE / 10
且 还有pop
需要添加 时,则一定溢出
当出现ans == MIN_VALUE / 10
且pop < -8
时,则一定溢出,8
是-2^31
的个位数
解题代码2:
class Solution {
public int reverse(int x) {
int ans = 0;
while (x != 0) {
int pop = x % 10;
if (ans > Integer.MAX_VALUE / 10 || (ans == Integer.MAX_VALUE / 10 && pop > 7))
return 0;
if (ans < Integer.MIN_VALUE / 10 || (ans == Integer.MIN_VALUE / 10 && pop < -8))
return 0;
ans = ans * 10 + pop;
x /= 10;
}
return ans;
}
}
2. 回文数(简单)
题目描述:
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例1:
输入: 121
输出: true
示例2:
输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例3:
输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。
进阶:
你能不将整数转为字符串来解决这个问题吗?
解题思路:
- 如果
x
为负数,则返回false
。 - 如果
x
为正数,先将x
反转,比较反转前后是否相等。
解题代码:
class Solution {
public boolean isPalindrome(int x) {
if (x < 0) {
return false;
}
int res = 0;
int tmp = x;
while (tmp != 0) {
res = res * 10 + tmp % 10;
tmp = tmp / 10;
}
if (res == x) {
return true;
}
return false;
}
}
字符串
1. 有效的括号(简单)
题目描述:
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
示例1:
输入: "()"
输出: true
示例2:
输入: "()[]{}"
输出: true
示例3:
输入: "(]"
输出: false
示例4:
输入: "([)]"
输出: false
示例5:
输入: "{[]}"
输出: true
解题思路:
将匹配的括号放入map
,遇到左括号入栈,遇到右括号且栈非空时出栈,最后检查栈是否为空。
解题代码:
class Solution {
public boolean isValid(String s) {
if (s.equals("")) {
return true;
}
Map<String, String> map = Map.of(")","(", "}" , "{", "]" ,"[");
if (map.containsKey(String.valueOf(s.charAt(0)))) {
return false;
}
Stack<String> stack = new Stack<>();
for (int i = 0; i < s.length(); i++) {
String curStr = String.valueOf(s.charAt(i));
if (map.containsValue(curStr)) {
stack.push(curStr);
} else {
String res = map.get(curStr);
if (!stack.empty() && stack.peek().equals(res)) {
stack.pop();
} else {
return false;
}
}
}
if (stack.empty()) {
return true;
}
return false;
}
}