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 <= 15s仅含字符('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 <= 2000 <= strs[i].length <= 200strs[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] <= 104nums已按 非严格递增 排列
题解:
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 <= 1000 <= nums[i] <= 500 <= 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] <= 104nums为 无重复元素 的 升序 排列数组-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 <= 104s仅有英文字母和空格' '组成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 <= 1000 <= 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 <= 104a和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 + nnums2.length == n0 <= m, n <= 2001 <= 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 * 105s仅由可打印的 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^51 <= nums[i], target <= 10^5
题解:
使用双指针
1 | import java.util.Arrays; |














