20240506
实现一个方法 transform, 以数组为参数, 循环将数组中的每个元素 乘以 2 , 并设置到对应的数组元素上. 例如 原数组为 {1, 2, 3}, 修改之后为 {2, 4, 6}
public static void transform(int[] array){
for (int i = 0; i < array.length; i++) {
array[i] *= 2;
}
}
public static void main(String[] args) {
int[] array = {1,2,3};
transform(array);
System.out.println(Arrays.toString(array));
}
结果:
调整数组顺序使得奇数位于偶数之前。调整之后,不关心大小顺序。
如数组:[1,2,3,4,5,6]
调整后可能是:[1, 5, 3, 4, 2, 6]
public static void test(int[] array){
int i = 0;
int j = array.length - 1;
while(i < j){
while(i < j && array[i] % 2 != 0){
i++;
}
while(i < j && array[j] % 2 == 0){
j--;
}
int tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
}
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6};
test(array);
System.out.println(Arrays.toString(array));
}
解析:
给定一个有序整型数组, 实现二分查找
public static int binarySearch(int[] array,int key){
int left = 0;
int right = array.length - 1;
while(left <= right){
int mid = (left + right)/2;
if(array[mid] < key){
left = mid + 1;
}else if(array[mid] > key){
right = mid - 1;
}else{
return mid;
}
}
return -1;
}
public static void main(String[] args) {
int[] array = {1,2,3,4,5,6,7,8,9,10};
int ret = binarySearch(array,3);
if(ret == -1){
System.out.println("not found");
}else{
System.out.println("找到了,下标是:"+ ret);
}
}
给定一个整型数组,实现冒泡排序(升序)
错误示例:
正确示例:
public static void bubbleSort(int[] arr){
boolean flg = false;
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - i - 1; j++) {
if(arr[j] > arr[j+1]){
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
flg = true;
}
}
if(flg == false){
break;
}
}
}
public static void main(String[] args) {
int[] arr = {1,3,2,2,4};
bubbleSort(arr);
System.out.println(Arrays.toString(arr));
}
解析:
进一步进行了优化,当数据在排序过程当中有序了,会在某一趟排序后,发现数据没有交换。
所以,每一趟排序完,都去检查是否发生了交换,没有交换证明数据已近有序,不需要再进行剩余趟数的排序了。
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
下面是自己实现:
public static int[] test(int[] arr,int target){
for(int i=0;i<arr.length-1;i++){
for(int j = i+1;j<arr.length;j++){
if(arr[i] + arr[j] == target){
return new int[]{i,j};
}
}
}
return null;
}
public static void main(String[] args) {
int[] nums = {2,7,11,15};
int[] arr = test(nums,9);
System.out.println(Arrays.toString(arr));
}
下面是答案实现:
本题最重要的一句话:假设每种输入只会对应一个答案
也就意味着不会有多个答案,暴力求解就是挨个匹配查找即可
public static int[] twoSum(int[] nums,int target){
int[] result = new int[2];
//双向指针i和j,i从前向后遍历,j从后向i遍历
//若arr[i]+arr[j]=target,即为题解
for(int i=0;i<nums.length-1;i++){
for(int j = nums.length - 1;j > i;j--){
if(nums[i] + nums[j] == target){
result[0] = i;
result[1] = j;
}
}
}
return result;
}
public static void main(String[] args) {
int[] nums = {2,7,11,15};
int[] arr = twoSum(nums,9);
System.out.println(Arrays.toString(arr));
}
可以用哈希表来提升效率,后面学习之后再来改进
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
下面是自己实现:
public static int test(int[] arr){
for (int i = 0; i < arr.length; i++) {
int x = arr[i];
int j = 0;
int count = 0;
while(j < arr.length){
if(arr[j] == x){
count++;
//这里加了判断若count已经大于1,提前结束循环
if(count > 1){
break;
}
}
j++;
}
if(count == 1){
return x;
}
}
return -1;
}
public static void main(String[] args) {
int[] arr = {2,2,1,3,4,3,8,4,8,2,9,2,9};
int tmp = test(arr);
if(tmp == -1){
System.out.println("没找到");
}else{
System.out.println("找到了,该数字是:" + tmp);
}
}
下面是答案实现:
本题主要考察运算符:异或。
异或的特点是:
1、n ^ n = 0;即两个相同的数字异或是0
2、0 ^ n = n;即0和任何数字进行异或,结果就是那个任何数字。
public static int singleNumber(int[] nums){
//用异或运算的性质可以巧妙的解决这个问题
//因为数组中只有一个数字出现一次
//则其他出现两次的数字用异或运算后都是0
//最终整个数组异或运算的结果即为所求
int ret = 0;
for(int i : nums){
ret ^= i;
}
return ret;
}
public static void main(String[] args) {
int[] arr = {4,1,2,1,2};
int tmp = singleNumber(arr);
if(tmp == 0){
System.out.println("没找到");
}else{
System.out.println("找到了,该数字是:" + tmp);
}
}
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
例子:
自己实现:
public static int test(int[] arr){
for (int i = 0; i < arr.length; i++) {
int x = arr[i];
int j = 0;
int count = 0;
while(j < arr.length){
if(arr[j] == x){
count++;
//这里加了判断若count已经大于数组长度的1/2,提前结束循环
if(count > arr.length/2){
return x;
}
}
j++;
}
}
return -1;
}
public static void main(String[] args) {
int[] arr = {2,2,1,1,1,2,2};
int tmp = test(arr);
if(tmp == -1){
System.out.println("没找到");
}else{
System.out.println("找到了,该数字是:" + tmp);
}
}
答案实现:
数组中出现次数超过一半的数字,一定是排好序之后,中间位置的数字。
//将数组排序后,数组n/2的元素一定是众数
public static int majorityElement(int[] arr) {
Arrays.sort(arr);
return arr[arr.length/2];
}
public static void main(String[] args) {
int[] arr = {2,2,1,1,1,2,2};
int tmp = majorityElement(arr);
System.out.println(tmp);
}
给你一个整数数组 arr
,请你判断数组中是否存在连续三个元素都是奇数的情况:如果存在,请返回 true
;否则,返回 false
。
自己实现:
public static boolean test(int[] arr){
for (int i = 0; i < arr.length; i++) {
int x = arr[i];
int j = 0;
int count = 0;
while(j < arr.length){
if(arr[j] % 2 != 0){
count++;
//这里加了判断若count已经大于数组长度的1/2,提前结束循环
if(count > 2){
return true;
}
}else{
count = 0;
}
j++;
}
}
return false;
}
public static void main(String[] args) {
int[] arr = {1,2,34,3,4,5,7,23,12};
boolean tmp = test(arr);
if(tmp == false){
System.out.println("不存在连续三个元素都是奇数的情况");
}else{
System.out.println("存在连续三个元素都是奇数的情况");
}
}
答案实现:
数字是连续出现的,所以我们只需要定义一个计数器,如果连续出现的次数超过3,则返回true。
public static boolean threeConsecutiveOdds(int[] arr){
//引入标记位记录连续出现奇数的个数
int count = 0;
for (int i = 0; i < arr.length; i++) {
if(isConsecutiveOdd(arr[i])){
//出现奇数,count++;
count++;
if(count == 3){
//出现连着三个奇数,返回true
return true;
}
}else{
//碰到偶数,count重置
count = 0;
}
}
return false;
}
public static boolean isConsecutiveOdd(int num){
return num % 2 != 0;
}
public static void main(String[] args) {
int[] arr = {1,2,34,3,4,5,7,23,12};
boolean tmp = threeConsecutiveOdds(arr);
if(tmp == false){
System.out.println("不存在连续三个元素都是奇数的情况");
}else{
System.out.println("存在连续三个元素都是奇数的情况");
}
}
获取一个数二进制序列中所有的偶数位和奇数位,分别输出二进制序列。
思路:
一个数的二进制位数为32,下标为0~31
想要得到一个整数中的每一个二进制数字,只有让它每个二进制数字都按位与(&)上1
按位与:与0得0,与1得1
代码如下:需要注意的是for循环的开始条件与结束条件
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个数字:");
int n = sc.nextInt();
//从左往右数
System.out.print("二进制奇数位:");
for (int i = 31; i >= 1 ; i-=2) {
System.out.print(((n>>i) & 1) + " ");
}
System.out.println();//换行
System.out.print("二进制偶数位:");
for (int i = 30; i >= 0 ; i-=2) {
System.out.print(((n>>i) & 1) + " ");
}
}
猜数字游戏
20240510
关于包的说法,下列错误的是:
如下代码的输出结果是什么?
public class Test {
public int aMethod(){
static int i = 0;
i++;
return i;
}
public static void main(String args[]){
Test test = new Test();
test.aMethod();
int j = test.aMethod();
System.out.println(j);
}
}
20240514_继承_work
1、如下代码的 结果是什么 ?
class Base {
Base() {
System.out.print("Base");
}
}
public class Alpha extends Base {
public static void main( String[] args ) {
new Alpha();//1
//调用父类无参的构造方法
new Base();//2
}
}
在子类中每次创建新的对象,都会调用一次父类中的构造方法
2、A 派生出子类 B , B 派生出子类 C ,并且在 java 源代码有如下声明:
1. A a0=new A();
2. A a1=new B();
3. A a2=new C();
问以下哪个说法是正确的?()
A.只有第一行能通过编译
B.第1、2行能通过编译,但第3行编译出错
C.第1、2、3行能通过编译,但第2、3行运行时出错
D.第1行,第2行和第3行的声明都是正确的
解析:
主要疑问就是注释3处,此时A虽然不是C的直接父类,但是C依然间接继承了A的内容的,此时可以发生向上转型的。
故:选择D。
3、以下程序执行的结果是:
class X{
Y y=new Y();//1
public X(){//2
System.out.print("X");
}
}
class Y{
public Y(){//3
System.out.print("Y");
}
}
public class Z extends X{
Y y=new Y();//4
public Z(){//5
System.out.print("Z");
}
public static void main(String[] args) {
new Z();
}
}
A.ZYXX
B.ZYXY
C.YXYZ
D.XYZX
解析:
本题考察代码的执行顺序:
类Z继承类X。
在继承层次上,先执行父类和子类的静态的,再执行父类的实例,父类的构造,最后执行子类的实例和子类的构造。
根据以上顺序,我们得出结论:本题中没有静态的。所以先执行1和2,再执行4和5。执行注释1和注释4的时候,分班打印Y。故最终的结果是YXYZ。
故答案为:C
20240517——多态
以下代码运行输出的是
class B {
public int Func() {
System.out.print("B");
return 0;
}
}
class D extends B {
@Override
public int Func() {
System.out.print("D");
return 0;
}
}
public class Test {
public static void main(String[] args) {
B a = new B();
B b = new D();
a.Func();
b.Func();
}
}
解析:向上转型,用父类引用创建的子类对象,在调用func方法时,发生动态绑定,调用的是子类中重写的方法
2024-05-18_抽象类和接口
public interface IService {String NAME="default";}
默认类型等价表示是哪一项:
A.public String NAME="default";
B.public static String NAME="default";
C.public static final String NAME="default";
D.private String NAME="default";
解析:
接口当中的成员变量默认是:public static final
接口当中的成员方法默认是:public abstract
一般定义的时候不加,也是默认为以上的形式存在的
故:选择C
以下哪些方法是Object类中的方法?(多选)
A.clone()
B.toString()
C.wait()
D.finalize()
解析:
参考Object类的源码我们发现,所有方法均存在。
A:是用来进行对象的克隆
B:将对象的属性等信息,以字符串的形式输出
C:调用wait方法,当前线程进入等待状态
D:在对象被垃圾收集器析构(回收)之前调用,这个方法叫做 finalize( ),它用来清除回收对象。
String类OJ
字符串相加
给定两个字符串形式的非负整数 num1
和num2
,计算它们的和并同样以字符串形式返回。
你不能使用任何內建的用于处理大整数的库(比如 BigInteger
), 也不能直接将输入的字符串转换为整数形式。
示例 1:
输入:num1 = "11", num2 = "123" 输出:"134"
示例 2:
输入:num1 = "456", num2 = "77" 输出:"533"
示例 3:
输入:num1 = "0", num2 = "0" 输出:"0"
提示:
1 <= num1.length, num2.length <= 104
num1
和num2
都只包含数字0-9
num1
和num2
都不包含任何前导零
思路:
本题我们只需要对两个整数模拟「竖式加法」的过程。竖式加法就是我们平常学习生活中常用的对两个整数相加的方法,回想一下我们在纸上对两个整数相加的操作,将相同数位对齐,从低到高逐位相加,如果当前位和超过 10,则向高位进一位,我们只要将这个过程用代码写出来即可
具体实现也不复杂,我们定义两个指针 i 和 j 分别指向 num1 和 num2 的末尾,即最低位,同时定义一个变量 add 维护当前是否有进位,然后从末尾到开头逐位相加即可。当两个数字位数不同时,我们统一在指针当前下标处于负数的时候返回0,等价于对位数较短的数字进行了补零操作,这样就可以除去两个数字位数不同情况的处理,具体可以看下面的代码:
class Solution {
public String addStrings(String num1, String num2) {
int i = num1.length() - 1, j = num2.length() - 1, add = 0;
StringBuffer ans = new StringBuffer();
while (i >= 0 || j >= 0 || add != 0) {
int x = i >= 0 ? num1.charAt(i) - '0' : 0;
int y = j >= 0 ? num2.charAt(j) - '0' : 0;
int result = x + y + add;
ans.append(result % 10);
add = result / 10;
i--;
j--;
}
// 计算完以后的答案需要翻转过来
ans.reverse();
return ans.toString();
}
}
解析:
第一个只出现一次的字符
给定一个字符串 s
,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1
。
示例 1:
输入: s = "leetcode" 输出: 0
示例 2:
输入: s = "loveleetcode" 输出: 2
示例 3:
输入: s = "aabb" 输出: -1
提示:
1 <= s.length <= 105
s
只包含小写字母
public static int firstUniqChar(String s) {
int[] count = new int[26];
for (int i = 0; i < s.length(); i++) {
count[s.charAt(i) - 'a']++;
}
for(int j = 0; j < s.length();j++){
if(count[s.charAt(j) - 'a'] == 1){
return j;
}
}
return -1;
}
public static void main(String[] args) {
String str = "loveleetcode";
int ret = firstUniqChar(str);
System.out.println(ret);
}
解析:
字符串最后一个单词的长度
描述
计算字符串最后一个单词的长度,单词以空格隔开,字符串长度小于5000。(注:字符串末尾不以空格为结尾)
输入描述:
输入一行,代表要计算的字符串,非空,长度小于5000。
输出描述:
输出一个整数,表示输入字符串最后一个单词的长度。
示例:
输入:hello nowcoder
输出:8
说明:最后一个单词为nowcoder,长度为8
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
str.trim();//去除字符串前后的空格
String[] tmp = str.split(" ");//将字符串按空格为分隔符,分割为字符数组
System.out.println(tmp[tmp.length-1].length());//计算tmp 数组长度-1下标 的字符串的长度
}
验证回文串
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。
示例 1:
输入: s = "A man, a plan, a canal: Panama"
输出:true
解释:"amanaplanacanalpanama" 是回文串。
示例 2:
输入:s = "race a car"
输出:false
解释:"raceacar" 不是回文串。
示例 3:
输入:s = " "
输出:true
解释:在移除非字母数字字符之后,s 是一个空字符串 "" 。
由于空字符串正着反着读都一样,所以是回文串。
提示:
1 <= s.length <= 2 * 105
s 仅由可打印的 ASCII 字符组成
public static boolean isPalindrome(String s){
s = s.toLowerCase();
int left = 0;
int right = s.length() - 1;
while(left < right){
while(left < right && !isNumberAndCharacter(s.charAt(left))) {
left++;
}
while(left < right && !isNumberAndCharacter(s.charAt(right))) {
right--;
}
if(s.charAt(left) == s.charAt(right)) {
left++;
right--;
}else {
return false;
}
}
return true;
}
public static boolean isNumberAndCharacter(char ch){
if(Character.isDigit(ch) || Character.isLetter(ch)){
return true;
}
return false;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
System.out.println(isPalindrome(str));
}
解析:
指出下列程序运行的结果()
public class Example{
String str = new String("good");
char[ ] ch = { 'a' , 'b' , 'c' };
public static void main(String args[]){
Example ex = new Example();
ex.change(ex.str,ex.ch);
System.out.print(ex.str + " and ");
System.out.print(ex.ch);
}
public void change(String str,char ch[ ]){
str = "test ok";
ch[0] = 'g';
}
}
A.good and abc
B.good and gbc
C.test ok and abc
D.test ok and gbc
解析:
下面代码将输出什么内容:()
public class SystemUtil{
public static boolean isAdmin(String userId){
return userId.toLowerCase()=="admin";
}
public static void main(String[] args){
System.out.println(isAdmin("Admin"));
}
}
A.true
B.false
C.1
D.编译错误
解析:
本题主要考察的代码部分为:
return userId.toLowerCase()=="admin";
== 两边的是引用数据类型,比较的是地址是否相同,"admin"存放在常量池中,
我们查看 userId.toLowerCase() 方法的源码(JDK1.8中),发现最终返回值:return new String(形参...),并不是常量池的"admin",所以这里比较的结果就是false,选B
转换成小写字母
给你一个字符串 s ,将该字符串中的大写字母转换成相同的小写字母,返回新的字符串。
示例 1:
输入:s = "Hello"
输出:"hello"
示例 2:
输入:s = "here"
输出:"here"
示例 3:
输入:s = "LOVELY"
输出:"lovely"
解法一:利用String自带函数
class Solution {
public String toLowerCase(String s) {
return s.toLowerCase();
}
}
解法二:自己实现(两种方式)
//第一种方式
public static String toLowerCase(String s) {
if(s == null || s.length() == 0) {
return null;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
//大写字母进行转换
if(ch >= 'A' && ch <= 'Z') {
sb.append((char)(ch+32));
}else{
//小写字母直接拼接
sb.append(ch);
}
}
return sb.toString();
}
//第二种方式
public static String toLowerCase(String s) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if(ch >= 65 && ch <= 90) {
ch |= 32;
}
sb.append(ch);
}
return sb.toString();
}
解法三:
//这种字符串拼接因为要创建很多新对象,所以效率极低,更推荐用StringBuffer或StringBuilder
// public static String toLowerCase(String s) {
// String ret = "";
// for (int i = 0; i < s.length(); i++) {
// char ch = s.charAt(i);
// //判断当前字符是不是字母
// if(Character.isLetter(ch)) {
// //判断是不是大写字母
// if(Character.isUpperCase(ch)) {
// //因为ch + 32 发生了向上转型,变为int型4字节,char型的ch装不下,所以需要强转为char型
// ch = (char)(ch + 32);
// }
// }
// ret += ch;
// }
// return ret;
// }
public static String toLowerCase(String s) {
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
//判断当前字符是不是字母
if(Character.isLetter(ch)) {
//判断是不是大写字母
if(Character.isUpperCase(ch)) {
//因为ch + 32 发生了向上转型,变为int型4字节,char型的ch装不下,所以需要强转为char型
ch = (char)(ch + 32);
}
}
stringBuffer.append(ch);
}
return stringBuffer.toString();
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
System.out.println(toLowerCase(str));
}
字符串中的单词数
统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符。
请注意,你可以假定字符串里不包括任何不可打印的字符。
示例:
输入: "Hello, my name is John"
输出: 5
解释: 这里的单词是指连续的不是空格的字符,所以 "Hello," 算作 1 个单词。
以下是自己写的:
public static int countSegments(String s) {
String[] tmp = s.split(" ");
int count = 0;
for (int i = 0; i < tmp.length; i++) {
count++;
}
return count;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
System.out.println(countSegments(str));
}
欠缺之处:
- 没有考虑到参数为空和字符串为空的情况
- 没有考虑到字符串中有很多空格的情况,如右图这样:
优化后:
public static int countSegments(String s) {
s = s.trim();
if(s == null || s.isEmpty()) {
return 0;
}
String[] tmp = s.split(" ");
int count = 0;
for (int i = 0; i < tmp.length; i++) {
if(tmp[i].isEmpty()) { //用来判断字符串中有很多空格的情况
continue;
}
count++;
}
return count;
}
20240529——异常的基本用法
有关下述Java代码描述正确的选项是____。
public class TestClass {
private static void testMethod(){
System.out.println("testMethod");
}
public static void main(String[] args) {
((TestClass)null).testMethod();
}
}
A.编译不通过
B.编译通过,运行异常,报NullPointerException
C.编译通过,运行异常,报IllegalArgumentException
D.编译通过,运行异常,报NoSuchMethodException
E.编译通过,运行异常,报Exception
F.运行正常,输出testMethod
解析:
testMethod是静态方法,可以通过类名进行调用
将null强转为TestClass类型后,可以调用testMethod方法
(多选)下面有关JAVA异常类的描述,说法错误的是?
A. 异常的继承结构:基类为Throwable,Error和Exception继承Throwable,RuntimeException和IOException等继承Exception
B.非RuntimeException一般是外部错误(非Error),其必须被 try{}catch语句块所捕获
C. Error类体系描述了Java运行系统中的内部错误以及资源耗尽的情形,Error不需要捕捉
D.RuntimeException体系包括错误的类型转换、数组越界访问和试图访问空指针等等,必须被 try{}catch语句块所捕获
解析:
B选项指的是编译时异常/受查异常,我们如果不解决他,可以用throws声明,将异常交给JVM处理,这样就可以不用被try-catch所捕获
D选项是运行时异常/非受查异常,在运行时才会报错,编译时会正常通过,不用必须try-catch捕获
实现一个简单的控制台版用户登陆程序, 程序启动提示用户输入用户名密码. 如果用户名密码出错, 使用自定义异常的方式来处理
public class UserNameException extends RuntimeException{
public UserNameException() {
super();
}
public UserNameException(String s) {
super(s);
}
}
public class PassWordException extends RuntimeException{
public PassWordException() {
super();
}
public PassWordException(String s) {
super(s);
}
}
public class Login {
private String userName = "abc";
private String passWord = "123";
public void logInFo(String userName,String passWord) {
if(!this.userName.equals(userName)) {
throw new UserNameException("用户名错误异常!");
}
if(!this.passWord.equals(passWord)) {
throw new PassWordException("密码错误异常!");
}
System.out.println("登录成功!");
}
}
import java.util.Scanner;
public class Test {
public static void main(String[] args) throws UserNameException,PassWordException{
Login login = new Login();
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String userName = sc.nextLine();
System.out.println("请输入密码:");
String passWord = sc.nextLine();
try {
login.logInFo(userName,passWord);
}catch(UserNameException | PassWordException e) {
e.printStackTrace();
} finally {
}
}
}
方法一:转为字符串,利用前后指针
class Solution {
public boolean isPalindrome(int x) {
//负数、个位是0的数(数字0除外)都不是回文
if(x < 0 || x % 10 == 0 && x != 0) {
return false;
}
//int 类型转为 String 类型,三种方法
//String str = Integer.toString(x);
String str = x + "";
//String str = String.valueOf(x);
//利用前后指针的方法分别比较前后字符
int left = 0;
int right = str.length() - 1;
while(left < right) {
if(str.charAt(left) == str.charAt(right)) {
left++;
right--;
} else {
return false;
}
}
return true;
}
}
方法二:反转整数后半部分与前半部分进行比较
tip:
1. 考虑到反转后整数溢出问题,所以只反转数字的一半,而不是反转全部
2. 所有的负数都不是回文,因为负号不会对称
3. 个位为 0 的(除了数字 0)都不是回文,因为最高位不可能为 0
//不转为字符串
class Solution {
public boolean isPalindrome(int x) {
if (x < 0 || x % 10 == 0 && x != 0) {
return false;
}
int num = 0;
//在整个过程中不断的在将原始数字除以10,然后给反转后的数字乘上10
//所以当原始数字小于或等于反转后的数字时,就意味着已经处理了一半位数的数字了
while (x > num) {
//每次循环都把当前的 num 乘以10,再加上当前的 x%10
num = num * 10 + x % 10;
x /= 10;
}
//当数字为奇数时,可以通过 num/10 去除中位的数字,中位数字等于它本身可忽略
return x == num || x == num / 10;
}
}