JAVA 练习暑期篇
JAVA 练习暑期篇
mengnankkzhoujava编程练习
基础题
1.leetcode 回文数
给你一个整数 x
,如果 x
是一个回文整数,返回 true
;否则,返回 false
。
回文数
是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
- 例如,
121
是回文,而123
不是。
示例 1:
1 | 输入:x = 121 |
示例 2:
1 | 输入:x = -121 |
示例 3:
1 | 输入:x = 10 |
提示:
-231 <= x <= 231 - 1
题解:
1 | class Solution { |
循环条件:while(t > 0)
表示只要 t
大于 0
,就继续循环。即,只要还有未处理的数字,就继续反转。
反转步骤:
- 取个位数字:
t % 10
取t
的最后一位数字。例如,如果t
是1234
,t % 10
会得到4
。 - 构建反转后的数字:
y = y * 10 + t % 10
将当前的y
向左移动一位(乘以10
),然后加上取出的最后一位数字。这一步的效果是把t
的最后一位数字移到y
的末尾。例如,如果y
是123
,t % 10
是4
,那么y = y * 10 + t % 10
就会变成1234
。 - 移除已处理的位:
t /= 10
将t
除以10
,即移除t
的最后一位。例如,如果t
是1234
,t /= 10
会把t
变成123
。
2.leetcode 罗马数字转整数
罗马数字包含以下七种字符: I
, V
, X
, L
,C
,D
和 M
。
1 | 字符 数值 |
例如, 罗马数字 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:
1 | 输入: s = "III" |
示例 2:
1 | 输入: s = "IV" |
示例 3:
1 | 输入: s = "IX" |
示例 4:
1 | 输入: s = "LVIII" |
示例 5:
1 | 输入: s = "MCMXCIV" |
提示:
1 <= s.length <= 15
s
仅含字符('I', 'V', 'X', 'L', 'C', 'D', 'M')
- 题目数据保证
s
是一个有效的罗马数字,且表示整数在范围[1, 3999]
内 - 题目所给测试用例皆符合罗马数字书写规则,不会出现跨位等情况。
- IL 和 IM 这样的例子并不符合题目要求,49 应该写作 XLIX,999 应该写作 CMXCIX 。
- 关于罗马数字的详尽书写规则,可以参考 罗马数字 - 百度百科。
题解:
1 | import java.util.*; |
3.最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""
。
示例 1:
1 | 输入:strs = ["flower","flow","flight"] |
示例 2:
1 | 输入:strs = ["dog","racecar","car"] |
提示:
1 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i]
仅由小写英文字母组成
题解:
1 | public class Solution1 { |
4.leetcode删除有序数组中的重复项
给你一个 非严格递增排列 的数组 nums
,请你** 原地** 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums
中唯一元素的个数。
考虑 nums
的唯一元素的数量为 k
,你需要做以下事情确保你的题解可以被通过:
- 更改数组
nums
,使nums
的前k
个元素包含唯一元素,并按照它们最初在nums
中出现的顺序排列。nums
的其余元素与nums
的大小不重要。 - 返回
k
。
判题标准:
系统会用下面的代码来测试你的题解:
1 | int[] nums = [...]; // 输入数组 |
如果所有断言都通过,那么您的题解将被 通过。
示例 1:
1 | 输入:nums = [1,1,2] |
示例 2:
1 | 输入:nums = [0,0,1,1,1,2,2,3,3,4] |
提示:
1 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums
已按 非严格递增 排列
题解:
1 | class Soultion{ |
5.leetcode 移除元素
给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素。元素的顺序可能发生改变。然后返回 nums
中与 val
不同的元素的数量。
假设 nums
中不等于 val
的元素数量为 k
,要通过此题,您需要执行以下操作:
- 更改
nums
数组,使nums
的前k
个元素包含不等于val
的元素。nums
的其余元素和nums
的大小并不重要。 - 返回
k
。
用户评测:
评测机将使用以下代码测试您的解决方案:
1 | int[] nums = [...]; // 输入数组 |
如果所有的断言都通过,你的解决方案将会 通过。
示例 1:
1 | 输入:nums = [3,2,2,3], val = 3 |
示例 2:
1 | 输入:nums = [0,1,2,2,3,0,4,2], val = 2 |
提示:
0 <= nums.length <= 100
0 <= nums[i] <= 50
0 <= val <= 100
题解:
1 | public class Solution3 { |
6.leetcode 搜索插入位置(二分查找)
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n)
的算法。
示例 1:
1 | 输入: nums = [1,3,5,6], target = 5 |
示例 2:
1 | 输入: nums = [1,3,5,6], target = 2 |
示例 3:
1 | 输入: nums = [1,3,5,6], target = 7 |
提示:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums
为 无重复元素 的 升序 排列数组-104 <= target <= 104
题解:
使用二分查找
1 | class Solution { |
-
leetcode 最后一个单词的长度
给你一个字符串 s
,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。
单词 是指仅由字母组成、不包含任何空格字符的最大
子字符串
示例 1:
1 | 输入:s = "Hello World" |
示例 2:
1 | 输入:s = " fly me to the moon " |
示例 3:
1 | 输入:s = "luffy is still joyboy" |
提示:
1 <= s.length <= 104
s
仅有英文字母和空格' '
组成s
中至少存在一个单词
题解:
1 | class Solution5 { |
7.leetcode 加一(遍历)
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
1 | 输入:digits = [1,2,3] |
示例 2:
1 | 输入:digits = [4,3,2,1] |
示例 3:
1 | 输入:digits = [0] |
提示:
1 <= digits.length <= 100
0 <= digits[i] <= 9
题解:
1 | public class Solution { |
8.leetcode 二进制求和(二进制的转化)
给你两个二进制字符串 a
和 b
,以二进制字符串的形式返回它们的和。
示例 1:
1 | 输入:a = "11", b = "1" |
示例 2:
1 | 输入:a = "1010", b = "1011" |
提示:
1 <= a.length, b.length <= 104
a
和b
仅由字符'0'
或'1'
组成- 字符串如果不是
"0"
,就不含前导零
题解:
1 | class Solution6{ |
9.leetcode x 的平方根 (牛顿迭代法 暴力)
给你一个非负整数 x
,计算并返回 x
的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
**注意:**不允许使用任何内置指数函数和算符,例如 pow(x, 0.5)
或者 x ** 0.5
。
示例 1:
1 | 输入:x = 4 |
示例 2:
1 | 输入:x = 8 |
提示:
0 <= x <= 231 - 1
题解:
牛顿迭代法
首先随便猜一个近似值 x,然后不断令 x 等于 x 和 a/x 的平均数,迭代个六七次后 x 的值就已经相当精确了。
1 | public class Solution7 { |
还有一种类似的方法
1 | class Solution { |
这个主要是控制了下精度。让他在某个范围内就结束
10.leetcode爬楼梯
假设你正在爬楼梯。需要 n
阶你才能到达楼顶。
每次你可以爬 1
或 2
个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例 1:
1 | 输入:n = 2 |
示例 2:
1 | 输入:n = 3 |
提示:
1 <= n <= 45
题解:
即 f(n) 为以上两种情况之和,即 f(n)=f(n−1)+f(n−2) ,以上递推性质为斐波那契数列。因此,本题可转化为 求斐波那契数列的第 n 项,区别仅在于初始值不同。
1 | public class Solution8 { |
10.leetcode 删除排序链表中的重复元素(链表)
给定一个已排序的链表的头 head
, 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。
示例 1:
1 | 输入:head = [1,1,2] |
示例 2:
1 | 输入:head = [1,1,2,3,3] |
提示:
- 链表中节点数目在范围
[0, 300]
内 -100 <= Node.val <= 100
- 题目数据保证链表已经按升序 排列
题解:
1 | public class Solution9 { |
一个小测试代码:
1 | // 定义链表节点类 |
输出结果和期望一致
🦅了
11.leetcode 合并两个有序数组
给你两个按 非递减顺序 排列的整数数组 nums1
和 nums2
,另有两个整数 m
和 n
,分别表示 nums1
和 nums2
中的元素数目。
请你 合并 nums2
到 nums1
中,使合并后的数组同样按 非递减顺序 排列。
**注意:**最终,合并后数组不应由函数返回,而是存储在数组 nums1
中。为了应对这种情况,nums1
的初始长度为 m + n
,其中前 m
个元素表示应合并的元素,后 n
个元素为 0
,应忽略。nums2
的长度为 n
。
示例 1:
1 | 输入:nums1 = [1,2,3,0,0,0], m = 3, nums2 = [2,5,6], n = 3 |
示例 2:
1 | 输入:nums1 = [1], m = 1, nums2 = [], n = 0 |
示例 3:
1 | 输入:nums1 = [0], m = 0, nums2 = [1], n = 1 |
提示:
nums1.length == m + n
nums2.length == n
0 <= m, n <= 200
1 <= m + n <= 200
-109 <= nums1[i], nums2[j] <= 109
题解:
1 | public class Solution10 { |
12.leetcode 验证回文串(双指针)
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s
,如果它是 回文串 ,返回 true
;否则,返回 false
。
示例 1:
1 | 输入: s = "A man, a plan, a canal: Panama" |
示例 2:
1 | 输入:s = "race a car" |
示例 3:
1 | 输入:s = " " |
提示:
1 <= s.length <= 2 * 105
s
仅由可打印的 ASCII 字符组成
题解:
判断回文一般都是用双指针算法。这题和其他题不同的是有多余空或者符号,我们只要去掉这些多余空格和符号就行,再进行判断。
1 | public class Solution11 { |
13.leetocode 汉明距离
两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。
给你两个整数 x
和 y
,计算并返回它们之间的汉明距离。
示例 1:
1 | 输入:x = 1, y = 4 |
示例 2:
1 | 输入:x = 3, y = 1 |
提示:
0 <= x, y <= 231 - 1
题解:
一(比特值算法)
1 | public class Solution { |
本身不改变 x 和 y,每次取不同的偏移位进行比较,不同则加一
详细解析:
for (int i = 0; i < 32; i++)
:
- 这个循环迭代 32 次,每次
i
从 0 到 31。对于 32 位整数,这样可以检查所有的比特位。
int a = (x >> i) & 1;
:
x >> i
是将x
右移i
位。比如,如果i = 0
,那么x >> 0
就是x
本身;如果i = 1
,那么x >> 1
是x
右移 1 位。(x >> i) & 1
通过位与运算& 1
提取x
在第i
位的值。结果是0
或1
,代表第i
位的比特值。
int b = (y >> i) & 1;
:
- 类似地,这一行提取
y
在第i
位的比特值。
ans += a ^ b;
:
a ^ b
是异或运算。异或运算的结果是:如果a
和b
不相等,则结果为1
;如果a
和b
相等,则结果为0
。- 这行代码将
a
和b
的异或结果加到ans
上。每次异或结果为1
表示在这个位上x
和y
的比特不同,增加1
到ans
上。
return ans;
:
- 返回
ans
,它是x
和y
之间所有不同比特位的总数,即汉明距离。
二(右移统计)
1 | public class Solution { |
首先先将xy和1进行位与运算,提取其值为1或者0;
然后对a和b进行异或计算,看是不是相等,,然后将不相等的的和进行计算
然后xy分别向右开始移1位
最后return ans的值;
14.leetocode 汉明距离总和
给你一个整数数组 nums
,请你计算并返回 nums
中任意两个数之间 汉明距离的总和 。
题解:
一开始我是刚做了上面哪个题,然后我就想着直接沿着上面的思路继续做吧
然后我写了
1 | public class Solution12 { |
然后就哈哈了,我这个代码写的根本不对好吧。
然后我就看了wp然后发现人家写的怎么这么简单
1 | class Solution { |
汉明距离的贡献分析
- 汉明距离的定义: 汉明距离是两个数在相同位置的比特位不同的数量。换句话说,计算两个数字在对应位置上不同的比特位数。
- 逐位分析: 对于数组中的每一位(假设从第
i
位开始),我们需要计算所有数字在该位上为1
和为0
的数量。c
:在第i
位上为1
的数字的数量。n - c
:在第i
位上为0
的数字的数量,其中n
是数组的总长度。
- 计算该位的汉明距离贡献: 对于每个数字,在第
i
位上为1
的数字将与第i
位上为0
的数字产生不同的比特位。也就是说,对于每个在第i
位上为1
的数字,它都与所有在第i
位上为0
的数字之间产生了一个不同的比特位。因此,每个1
会与每个0
形成一个汉明距离的贡献。- 如果
c
个数字在第i
位上是1
,那么这些1
对每个在第i
位上是0
的数字(共有n - c
个)都有一个不同的比特位。 - 因此,在第
i
位上,汉明距离的总贡献是c * (n - c)
。
- 如果
举个例子
假设数组 nums
为 [1, 4, 2]
,我们要计算汉明距离贡献时考虑每一位的情况:
- 第 0 位(最低位):
nums
中的二进制表示是:[001, 100, 010]
- 在第 0 位上,有
2
个1
(001
和101
),1
个0
(100
)。 - 贡献:
2 * (3 - 2) = 2 * 1 = 2
- 第 1 位:
- 二进制表示:
[001, 100, 010]
- 在第 1 位上,有
1
个1
(010
),2
个0
(001
和100
)。 - 贡献:
1 * (3 - 1) = 1 * 2 = 2
- 二进制表示:
- 第 2 位:
- 二进制表示:
[001, 100, 010]
- 在第 2 位上,有
1
个1
(100
),2
个0
(001
和010
)。 - 贡献:
1 * (3 - 1) = 1 * 2 = 2
- 二进制表示:
将所有位上的贡献加起来,总汉明距离是 2 + 2 + 2 = 6
。
15.leetcode心算挑战
暂时未解决
16.leetcode 采购方案
小力将 N 个零件的报价存于数组 nums
。小力预算为 target
,假定小力仅购买两个零件,要求购买零件的花费不超过预算,请问他有多少种采购方案。
注意:答案需要以 1e9 + 7 (1000000007)
为底取模,如:计算初始结果为:1000000008
,请返回 1
示例 1:
输入:
nums = [2,5,3,5], target = 6
输出:
1
解释:预算内仅能购买 nums[0] 与 nums[2]。
示例 2:
输入:
nums = [2,2,1,9], target = 10
输出:
4
解释:符合预算的采购方案如下: nums[0] + nums[1] = 4 nums[0] + nums[2] = 3 nums[1] + nums[2] = 3 nums[2] + nums[3] = 10
提示:
2 <= nums.length <= 10^5
1 <= nums[i], target <= 10^5
题解:
使用双指针
1 | import java.util.Arrays; |