Java se 编程题练习总结
1.回文数
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例 1:
输入: 121
输出: true
示例 2:
输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。
class Solution {
public boolean isPalindrome(int x) {
if( x < 0 )
return false;
/*
123456 % 10 = 6 renum * 10 + 6 = 6
12345 % 10 = 5 renum * 10 + 5 = 65
1234 % 10 = 4 renum * 10 + 4 = 654
*/
int temp = x;
int renum = 0;
while(temp != 0){
renum = renum * 10 + temp % 10;
temp = temp / 10;
}
return renum == x;
}
}
解题思路:首先如果输入数字小于0则输出false,其次分析回文数字的规律:
/*
123456 % 10 = 6 renum(0) * 10 + 6 = 6
12345 % 10 = 5 renum (6)* 10 + 5 = 65
1234 % 10 = 4 renum (65)* 10 + 4 = 654
......
*/
2.整数反转
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
示例 1:
输入:x = 123
输出:321
示例 2:
输入:x = -123
输出:-321
示例 3:
输入:x = 120
输出:21
示例 4:
输入:x = 0
输出:0
提示:-231 <= x <= 231 - 1
class Solution {
public int reverse(int x) {
/*
1234 1234 % 10 = 4 0 + 4 = 4
123 123 % 10 = 3 4 * 10 + 3 = 43
12 12 % 10 = 2 43 * 10 + 2 = 432
*/
long renum = 0;
while (x != 0) {
renum = renum * 10 + x % 10;
x /= 10;
}
return (int)renum == renum ? (int)renum: 0;
}
解题思路:分析规律:
/*
1234 1234 % 10 = 4 0 * 10 + 4 = 4
123 123 % 10 = 3 4 * 10 + 3 = 43
12 12 % 10 = 2 43 * 10 + 2 = 432
*/
在计算出后判断反转数字是否相同,如果不同,证明发生溢出,返回0。
3.罗马数字转整数
难度简单1182收藏分享切换为英文接收动态反馈
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 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 到 3999 的范围内。
示例 1:
输入: "III"
输出: 3
示例 2:
输入: "IV"
输出: 4
示例 3:
输入: "IX"
输出: 9
示例 4:
输入: "LVIII"
输出: 58
解释: L = 50, V= 5, III = 3.
示例 5:
输入: "MCMXCIV"
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.
提示:
题目所给测试用例皆符合罗马数字书写规则,不会出现跨位等情况。
IC 和 IM 这样的例子并不符合题目要求,49 应该写作 XLIX,999 应该写作 CMXCIX 。
关于罗马数字的详尽书写规则,可以参考 罗马数字 - Mathematics 。
class Solution {
public int romanToInt(String s) {
int num = s.length();
int roman = 0;
for(int i = 0;i < num;i++){
switch(s.charAt(i)) {
case 'I' : roman = roman + 1;
break;
case 'V' : roman = roman + 5;
break;
case 'X' : roman = roman + 10;
break;
case 'L' : roman = roman + 50;
break;
case 'C' : roman = roman + 100;
break;
case 'D' : roman = roman + 500;
break;
case 'M' : roman = roman + 1000;
break;
default: System.out.println("default");
break;
}
if(i!=0) {
if(((s.charAt(i)=='V')||(s.charAt(i)=='X'))&&(s.charAt(i-1)=='I'))
roman = roman-1*2;
if(((s.charAt(i)=='L')||(s.charAt(i)=='C'))&&(s.charAt(i-1)=='X'))
roman = roman-10*2;
if(((s.charAt(i)=='D')||(s.charAt(i)=='M'))&&(s.charAt(i-1)=='C'))
roman = roman-100*2;
}
}
return roman;
}
}
解题思路:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
4.最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 ""。
示例 1:
输入:strs = ["flower","flow","flight"]
输出:"fl"
示例 2:
输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。
提示:
0 <= strs.length <= 200
0 <= strs[i].length <= 200
strs[i] 仅由小写英文字母组成
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs.length==0)
return "";
String s = strs[0];
if (strs.length == 1)
return strs[0];
for (int i = 0; i < strs.length; i++) {
if (!strs[i].startsWith(s)) {
s = s.substring(0, s.length() - 1);
i--;
}
}
return s;
}
}
解题思路:所求的最长公共前缀子串一定是每个字符串的前缀子串。所以随便选择一个字符串作为标准,把它的前缀串,与其他所有字符串进行判断,看是否是它们所有人的前缀子串。从下标0开始,判断每一个字符串的下标0,判断是否全部相同。直到遇到不全部相同的下标。
5.有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
注意空字符串可被认为是有效字符串。
示例 1:
输入: "()"
输出: true
示例 2:
输入: "()[]{}"
输出: true
示例 3:
输入: "(]"
输出: false
示例 4:
输入: "([)]"
输出: false
示例 5:
输入: "{[]}"
输出: true
class Solution {
public boolean isValid(String s) {
if (s.length() % 2 != 0) {
return false;
}
int length = s.length() / 2;
for (int i = 0; i < length; i++) {
s = s.replace("()", "").replace("{}", "").replace("[]", "");
}
return s.length() == 0;
}
}
解题思路:找字符串中正确的替换成空的,最终长度返回0为true。
6. x 的平方根
实现 int sqrt(int x) 函数。
计算并返回 x 的平方根,其中 x 是非负整数。
由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。
示例 1:
输入: 4
输出: 2
示例 2:
输入: 8
输出: 2
说明: 8 的平方根是 2.82842...,
由于返回类型是整数,小数部分将被舍去。
class Solution {
public int mySqrt(int x) {
return (int)Math.sqrt(x);
}
}
解题思路:Math类的指数函数
sqrt(x) | 对于 x >=0 的数字,返回 x 的平方根 |
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例 1:
输入:[3,2,3]
输出:3
示例 2:输入:[2,2,1,1,1,2,2]
输出:2
分析图:
代码:
class Solution {
public int majorityElement(int[] nums) {
//思路2:正负相消
int m = nums[0];
int count = 1;
for (int i = 0; i < nums.length; i++) {
if (m == nums[i]) {
count++;
} else {
count--;
if (count == 0) {
m = nums[i];
count = 1;
}
}
}
return m;
}
}
给定一个非负整数数组 A,返回一个数组,在该数组中, A 的所有偶数元素之后跟着所有奇数元素。
你可以返回满足此条件的任何数组作为答案。
示例:
输入:[3,1,2,4]
输出:[2,4,3,1]
输出 [4,2,3,1],[2,4,1,3] 和 [4,2,1,3] 也会被接受。
提示:
1 <= A.length <= 5000
0 <= A[i] <= 5000
分析图:
代码:
class Solution {
public int[] sortArrayByParity(int[] A) {
int l = 0;
int r = A.length - 1;
while (l < r) {
//左奇右偶
if(A[l] % 2 == 1 && A[r] % 2 == 0) {
int temp = A[l];
A[l] = A[r];
A[r] = temp;
//左偶右奇
} else if (A[l] % 2 == 0 && A[r] % 2 == 1) {
l++;
r--;
//左奇右奇
} else if (A[l] % 2 == 1 && A[r] % 2 == 1) {
r--;
//左偶右偶
} else {
l++;
}
}
return A;
}
}
给你一个整数数组 A,只有可以将其划分为三个和相等的非空部分时才返回 true,否则返回 false。
形式上,如果可以找出索引 i+1 < j 且满足 A[0] + A[1] + ... + A[i] == A[i+1] + A[i+2] + ... + A[j-1] == A[j] + A[j-1] + ... + A[A.length - 1] 就可以将数组三等分。
示例 1:
输入:[0,2,1,-6,6,-7,9,1,2,0,1]
输出:true
解释:0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1
示例 2:输入:[0,2,1,-6,6,7,9,-1,2,0,1]
输出:false
示例 3:输入:[3,3,6,5,-2,2,5,1,-9,4]
输出:true
解释:3 + 3 = 6 = 5 - 2 + 2 + 5 + 1 - 9 + 4
分析图:
代码:
class Solution {
public boolean canThreePartsEqualSum(int[] arr) {
int sum = 0;
//foreach循环,num->arr
for (int num : arr){
sum += num;
}
int key = sum / 3;
int group = 0;
for (int i = 0; i < arr.length; i++) {
key -= arr[i];
if (key == 0) {
group++;
key = sum / 3;
}
}
return group == 3 || sum == 0 && group >= 3;
}
}
10.66. 加一
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。
示例 2:输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:输入数组表示数字 4321。
示例 3:输入:digits = [0]
输出:[1]
提示:
1 <= digits.length <= 100
0 <= digits[i] <= 9
分析图:
代码:
class Solution01 {
public int[] plusOne(int[] digits) {
int carry = 1;//最开始的进位 给个位加的
for (int i = digits.length; i >= 0; i--) {
int num = digits[i] + carry;
digits[i] = num % 10;
carry = num / 10;
if (carry == 0) {
break;
}
}
if (carry == 1) {
int[] arr = new int[digits.length + 1];
arr[0] = carry;
return arr;
}
}
return digits;
}
/*
升级版:
[1,2,3]
[4,5,6]
[5,7,9]
[1,2,3]
[9,8,7]
[1,0,0,0]
[1,2,3]
[5,6,7,8,9]
[5,6,9,1,2]
[1,2,3]
[9,9,9,9,9]
[1,0,0,1,2,2]
*/
public static void main(String[] args) {
}
class Solution01 {
public int[] plus(int[] digits1, int digits2) {
if (digits1.length < digits2.length) {
digits1 = kuorong(digits1, digits2,length);
} else if (digits2.length < digits1.length) {
digits2 = kuorong(digits2,digits1.length);
}
int carry = 0;
for (int i = digits1.length - 1; i >= 0; i--) {
int num = digits[i] + digits2[i] + carry;
carry = num / 10;
digits1[i] = num % 10;
}
if (carry == 1) {
int digits3 = new int[digits1.length + 1];
digits3[0] = 1;
for (int i = 0; i < digits1.length; i++) {
digits3[i + 1] = digits1[i];
}
return digits3;
}
return digits1;
}
public int kuorong(int[] arr,int newlen) {
// 1 2 3
// i
//9 9 9 9 9
// k
int newArr = new int[newlen];
int i = arr.length - 1;
int k = newArr.length - 1;
while (i >= 0) {
newArr[k--] = arr[i--];
}
return newArr;
}
}
给你一个整数数组 nums,请编写一个能够返回数组 “中心索引” 的方法。
数组 中心索引 是数组的一个索引,其左侧所有元素相加的和等于右侧所有元素相加的和。
如果数组不存在中心索引,返回 -1 。如果数组有多个中心索引,应该返回最靠近左边的那一个。
注意:中心索引可能出现在数组的两端。
示例 1:
输入:nums = [1, 7, 3, 6, 5, 6]
输出:3
解释:
索引 3 (nums[3] = 6) 的左侧数之和 (1 + 7 + 3 = 11),与右侧数之和 (5 + 6 = 11) 相等。
同时, 3 也是第一个符合要求的中心索引。
示例 2:输入:nums = [1, 2, 3]
输出:-1
解释:
数组中不存在满足此条件的中心索引。
示例 3:输入:nums = [2, 1, -1]
输出:0
解释:
索引 0 左侧不存在元素,视作和为 0 ;右侧数之和为 1 + (-1) = 0 ,二者相等。
示例 4:输入:nums = [0, 0, 0, 0, 1]
输出:4
解释:
索引 4 左侧数之和为 0 ;右侧不存在元素,视作和为 0 ,二者相等。
分析图:
代码:
class Solution {
public int pivotIndex(int[] nums) {
int sum = 0;
for (int num : nums) {
sum += num;
}
int left = 0;
int right = 0;
for (int i = 0; i < nums.length; i++) {
if (i == 0) {
left = 0;
} else {
left += nums[i-1];
}
right = sum - left - nums[i];
if (left == right) {
return i;
}
}
return -1;
}
}
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
分析图:
代码:
class Solution {
public int minSubArrayLen(int s, int[] nums) {
int len = 0;
int i = 0;
int sum = 0;
for (int j = 0; j < nums.length; j++) {
sum += nums[j];
while (sum >= s) {
len = len == 0 ? (j - i + 1) : Math.min(j - i + 1,len);
sum = sum - nums[i];
i++;
}
}
return len;
}
}