Java面试编程题积累-题目+详细解法——【第一周】

目录

day1

100449-组队竞赛

69390-删除公共字符

day2

题目ID:100448 排序子序列

69389-倒置字符串

day3

题目ID:69385--字符串中找出连续最长的数字串

23271-数组中出现次数超过一半的数字

day4

题目ID:46579 --计算糖果

58541-进制转换

day5

题目ID:45842-统计回文

58539-连续最大和

day6

题目ID:45840-不要二

23292-字符串转成整数

day7

题目ID:45846 --Fibonacci数列

题目ID:36939-合法括号序列判断

day8

题目ID:45844 --两种排序方法

题目ID:36932-求最小公倍数


day1

100449-组队竞赛

链接:组队竞赛_牛客笔试题_牛客网
来源:牛客网
牛牛举办了一次编程比赛,参加比赛的有3*n个选手,每个选手都有一个水平值a_i.现在要将这些选手进行组队,一共组成n个队伍,即每个队伍3人.牛牛发现队伍的水平值等于该队伍队员中第二高水平值。
例如:
一个队伍三个队员的水平值分别是3,3,3.那么队伍的水平值是3
一个队伍三个队员的水平值分别是3,2,3.那么队伍的水平值是3
一个队伍三个队员的水平值分别是1,5,2.那么队伍的水平值是2
为了让比赛更有看点,牛牛想安排队伍使所有队伍的水平值总和最大。
如样例所示:
如果牛牛把6个队员划分到两个队伍
如果方案为:
team1:{1,2,5}, team2:{5,5,8}, 这时候水平值总和为7.
而如果方案为:
team1:{2,5,8}, team2:{1,5,5}, 这时候水平值总和为10.
没有比总和为10更大的方案,所以输出10.
【题目解析】:
队伍的水平值等于该队伍队员中第二高水平值,为了所有队伍的水平值总和最大的解法,也就是说每个队伍的第二个值是尽可能大的值。所以实际值把最大值放到最右边,最小是放到最左边。
【解题思路】:
本题的主要思路是贪心算法,贪心算法其实很简单,就是每次选值时都选当前能看到的局部最解忧,所以这里的贪心就是保证每组的第二个值取到能选择的最大值就可以,我们每次尽量取最大,但是最大的数不可能是中位数,所以退而求其次,取 每组中第二大的
例如 现在排序后 有 1 2 5 5 8 9 ,那么分组为1 8 9 和 2 5 5
关系arr[arr.length-2*(i+1)]

import java.util.*;
public class Main{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while(scan.hasNextInt()) {
int n = scan.nextInt();
long[] array = new long[3*n];
for(int i = 0;i < (3*n);i++) {
array[i] = scan.nextLong();
}
Arrays.sort(array);
long sum = 0;
for (int i = 0; i < n; i++) {
sum += array[array.length-(2*(i+1))];
}
System.out.println(sum);
}
}
}

69390-删除公共字符

链接:https://www.nowcoder.com/practice/f0db4c36573d459cae44ac90b90c6212?tpId=85&&tqId=29868&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking
【题目解析】:

输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”

本题描述很简单,题目描述很清楚,读题即可
【解题思路】:
本题如果使用传统的暴力查找方式,如判断第一个串的字符是否在第二个串中,在再挪动字符删除这个字符的方式,效率为O(N^2),效率太低,很难让人满意。
1. 将第二个字符串的字符都映射到一个hashtable数组中,用来判断一个字符在这个字符串。
2. 判断一个字符在第二个字符串,不要使用删除,这样效率太低,因为每次删除都伴随数据挪动。这里可以考虑使用将不在字符添加到一个新字符串,最后返回新新字符串。

import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String str1 = scan.nextLine();//They are students.
String str2 = scan.nextLine();//aeiou
HashMap<Character,Integer> map = new HashMap<>();
for(int i = 0;i < str2.length();i++) {
if(map.get(str2.charAt(i)) == null) {
map.put(str2.charAt(i),1);
}else {
map.put(str2.charAt(i),map.get(str2.charAt(i))+1);
}
}
String ret = "";
for(int i = 0;i < str1.length();i++) {
if(map.get(str1.charAt(i)) == null) {
ret += str1.charAt(i);
}
}
System.out.println(ret);
}
}

day2

题目ID:100448 排序子序列

链接:https://www.nowcoder.com/questionTerminal/2d3f6ddd82da445d804c95db22dcc471?orderByHotValue=1&page=1&onlyReference=false
【题目解析】:

链接:排序子序列_牛客笔试题_牛客网
来源:牛客网

牛牛定义排序子序列为一个数组中一段连续的子序列,并且这段子序列是非递增或者非递减排序的。牛牛有一个长度为n的整数数组A,他现在有一个任务是把数组A分为若干段排序子序列,牛牛想知道他最少可以把这个数组分为几段排序子序列.
如样例所示,牛牛可以把数组A划分为[1,2,3]和[2,2,1]两个排序子序列,至少需要划分为2个排序子序列,所以输出2
本题要求解的是排序子序列,排序子序列为非递增或者非递减,很多同学在这个非递增、非递减问题上很纠结,注意:非递减就是a[i]<=a[i+1],递减就是a[i]>a[i+1],非递增就是a[i]>=a[i+1],递增就是a[i]<a[i+1]。
其实这个不理解网上搜一下就理解了。
【解题思路】:
1. 本题依次比较整个数组
2. a[i+1]>a[i] ,则进入非递增序列判断,直到遍历到下一个值不大于等于为止count++,然后进行下一位置的判断
3. a[i+1]<a[i],则进入非递增序列判断,直到遍历到下一个值不小于等于为止count++,然后进行下一位置的判断
4. a[i+1] == a[i]不进行操作,++i进行下一位置遍历,因为相等既可以属于非递增序列,也可以属于非递减序列。
本题注意点:本题开始比较a[i+1]与a[i]进行比较,为了避免越界,数组定义为n+1个,同时给a[n] = 0;a[n] = 0带来的影响,我们分为三种情况讨论:
1. 若到a[n-1] 的最后一组是非递减序列,当i==n-1,a[i] >a[i+1],因为前面的数都是大于0的,这个输入条件已经说明了(去看看题目输入条件描述),里面的循环结束,i++,count++,i==n,外面的循环结束。
2. 若到a[n-1] 的最后一组是非递增序列,当i==n-1,a[i] >a[i+1],因为前面的数都是大于0的,这个输入条件已经说明了(去看看题目输入条件描述),循环再走一次,i++, i== n,里面的循环结束,i++,count++,i==n+1,外面的循环结束。
3. 第三种情况 1 2 1 2 1最后一个数是单独的情况,后面补个0,序列变成1 2 1 2 1 0,当走完全面的序列i==n-1时,a[i] > a[i+1],进入判断出一个非递增序列,count++,i++,循环结束。
4. 也就是说数组最后一个位置多增加一个0,不会影响第1、2情况的判断,主要是帮助第3情况的正确判断。

import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
//长度给n+1防止越界
int[] array = new int[n+1];
for(int i = 0;i < n;i++) {
array[i] = scan.nextInt();
}
int i = 0;
int count = 0;
while(i < n) {
//进入非递减子序列
if(array[i] < array[i+1]) {
while(i < n && array[i] <= array[i+1]) {
}
count++;
i++;
}else if(array[i] == array[i+1]) {
i++;
}else {
while(i < n && array[i] >= array[i+1]) {
}
count++;
i++;
}
}
System.out.println(count);
}
}

69389-倒置字符串

https://www.nowcoder.com/practice/ee5de2e7c45a46a090c1ced2fdc62355?tpId=85&&tqId=29867&rp
=1&ru=/activity/oj&qru=/ta/2017test/question-ranking
【题目解析】:将一句话的单词进行倒置,标点不倒置。比如 I like beijing. 经过函数后变为:beijing. like I
本题题意很简单,就是将一段字符串中的前后单词交换,以单词为单位逆置。
【解题思路1】
先将整个字符串逆置过来,再遍历字符串,找出每个单词,对单词逆置。

import java.util.*;
public class Main{
public static void reverse(char[] array,int start,int end) {
while(start < end) {
char tmp = array[start];
array[start] = array[end];
array[end] = tmp;
start++;
end--;
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String s = scan.nextLine();
char[] ch = s.toCharArray();
int len = ch.length;
//1、整体进行了逆置
reverse(ch,0,len-1);
int i = 0;//遍历ch数组
while( i < len ) {
int j = i;
while(j < len && ch[j] != ' ') {
j++;
}
if(j < len) {
reverse(ch,i,j-1);
i = j+1;
}else{
reverse(ch,i,j-1);
i = j;
}
}
String str = new String(ch);
System.out.println(str);
}
}

day3

题目ID:69385--字符串中找出连续最长的数字串


链接:https://www.nowcoder.com/practice/bd891093881d4ddf9e56e7cc8416562d?tpId=85&&tqId=29864&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking
【题目解析】:读入一个字符串str,输出字符串str中的连续最长的数字串
本题是一个很简单的题目,这里就不解析了。
【解题思路】
遍历字符串,使用cur去记录连续的数字串,如果遇到不是数字字符,则表示一个连续的数字串结束了,则将数字串跟之前的数字串比较,如果更长,则更新更长的数字串更新到res。

import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
String ret = "";
String cur = "";
int i = 0;
for(;i < str.length();i++) {
char ch = str.charAt(i);
if(ch >= '0' && ch <= '9') {
cur = cur + ch+"";
}else{
if(ret.length() < cur.length()) {
}
cur =
}
}
//处理123abc123456这种情况
if(i== str.length() && ret.length()< cur.length()) {
ret = cur;
}
}

23271-数组中出现次数超过一半的数字


https://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163?tpId=13&tqId=11181&tPage=2&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
【题目解析】:

给一个长度为 n 的数组,数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。

本题题意很简单,需要找出超过一半的那个数字。需要注意这个题是一个往年面试的热门题型
【解题思路1】:
思路一:数组排序后,如果符合条件的数存在,则一定是数组中间那个数。这种方法虽然容易理解,但由于涉及到快排sort,其时间复杂度为O(NlogN)并非最优;

import java.util.*;
public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array == null || array.length == 0) {
return 0;
}
Arrays.sort(array);
int len = array.length;
int midNum = array[len/2];
int count = 0;
for(int i = 0;i < len;i++) {
if(array[i] == midNum) {
count++;
}
}
if(count > len/2) {
return midNum;
}
return 0;
}
}

【解题思路2】:
众数:就是出现次数超过数组长度一半的那个数字
如果两个数不相等,就消去这两个数,最坏情况下,每次消去一个众数和一个非众数,那么如果存在众数,最后留下的数肯定是众数。

public class Solution {
public int MoreThanHalfNum_Solution(int [] array) {
if(array == null || array.length==0) {
return 0;
}
int result = array[0];
int times = 1; // 次数
for(int i=1;i<array.length;++i){
if(times != 0){
if(array[i] == result) {
++times; // 相同则加1
}else{
--
times; // 不同则减1
}
}
else {
// 更新result的值为当前元素,并置次数为1
result = array[i];
times = 1;
}
}
// 判断result是否符合条件,即出现次数大于数组长度的一半
times = 0;
for(int i=0;i<array.length;++i){
if(array[i] == result) ++times;
}
return (times > array.length/2) ? result : 0;
}
}

day4

题目ID:46579 --计算糖果


链接:https://www.nowcoder.com/practice/02d8d42b197646a5bbd0a98785bb3a34?tpId=85&&tqId=2
9857&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking
【题目解析】:

A,B,C是三个人手里的糖果数量,我们不知道A,B,C是多少?但是我们知道A - B, B - C, A + B, B + C的结果,
这个结果题目是通过输入测试用例给我们的。所以本题本质是一个表达式求解问题。
【解题思路】:
1、A - B = a 2、B - C = b 3、A + B = c 4、B + C = d 这道题目的实质是:判断三元一次方程组是否有解及求解, 这里是小学生都会的问题了

^^ 1+3可以得到A=(a+c)/2;4-2可以得到C=(d-b)/2;
2+4可以得到B2=(b+d)/2,3-1可以得到B1=(c-a)/2;
如果B1不等B2则表达式无解

import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int a = in.nextInt();
int b = in.nextInt();
int c = in.nextInt();;
int d = in.nextInt();;
int A = (a+c)/2;
int C = (d-b)/2;
int B1 = (b+d)/2;
int B2 = (c-a)/2;
if(B1 != B2) {
System.out.print("No");
}else{
System.out.print(A+" "+B2+" "+C);
}
}
}

58541-进制转换


https://www.nowcoder.com/practice/ac61207721a34b74b06597fe6eb67c52?tpId=85&&tqId=29862&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking
【题目解析】:给定一个十进制数M,以及需要转换的进制数N。将十进制数M转化为N进制数
本题题目很简单,题目的本意就是将10进制的数转换成N进制。N(2 ≤ N ≤ 16)可以看出进制最多可以到16进制。
【解题思路】:
本题思路很简单,首先想清楚原理:N进制数,每个进制位的值分别是X0*N^0,X1*N^1, X2*N^2.....,X0,X1,X2就是这些进制位的值,就是就是进行取模余数就是当前低进制的位的值是多少,通过除掉进制数,进入下一个进制位的计算。

import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int m = in.nextInt();
int n = in.nextInt();
boolean flg = false;//代表不是小数
String table = "0123456789ABCDEF";
StringBuilder ret = new StringBuilder();
if(m < 0) {
m = -m;
flg = true;
}
while(m != 0) {
ret.append(table.charAt(m%n));
m = m/n;
}
if(flg) {
ret.append("-");
}
ret.reverse();
System.out.println(ret);
}
}

day5

题目ID:45842-统计回文


链接:https://www.nowcoder.com/practice/9d1559511b3849deaa71b576fa7009dc?tpId=85&&tqId=29842&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking
【题目解析】:“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。花花非常喜欢这种拥有对称美的回文串,生日的时候她得到两个礼物分别是字符串A和字符串B。现在她非常好奇有没有办法将字符串B插入字符串A使产生的字符串是一个回文串。你接受花花的请求,帮助她寻找有多少种插入办法可以使新串是一个回文串。如果字符串B插入的位置不同就考虑为不一样的办法。
例如:
A = “aba”,B = “b”。这里有4种把B插入A的办法:
* 在A的第一个字母之前: "baba" 不是回文
* 在第一个字母‘a’之后: "abba" 是回文
* 在字母‘b’之后: "abba" 是回文
* 在第二个字母'a'之后 "abab" 不是回文
所以满足条件的答案为2
首先以后面对这种题目描述比较长的题,不要害怕,它里面的大部分描述都只是为题做铺垫,所以读题时抓住重点。什么是回文字符串,题目里面说就是一个正读和反读都一样的字符串 ,回文串也就是前后对称的字符串。本题是判断是否是回文串的变形题。字符串本身不一定是回文,把第二个字符串插入进去看是否是回文。
【解题思路】:
本题使用暴力求解方式计算即可,遍历str1,将str2 insert进入str1的每个位置,判断是否是回文,这里注意的是,判断回文的时候,直接将字符串逆置,看是否相同就好了。是就++count;需要注意的是这里不能str1.insert(i, str2),这样的话str1改变了,判断下一个位置就不对了。所以每次使用str1重新给一个str,然后str.insert(i, str2),再判断。

import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str1 = sc.nextLine();
String str2 = sc.nextLine();
int len = str1.length();
int n = 0;
for (int i = 0; i <= len; i++) {
// 将字符串2插入到字符串1的每个位置,再判断是否是回文
StringBuffer str = new StringBuffer(str1);
str.insert(i, str2);
//注意这里,不能直接StringBuilder str5 = str.reverse();
//因为这样str本身又变了。
StringBuilder tmp = new StringBuilder(str);
StringBuilder str5 = tmp.reverse();
if (str.toString().equals(str5.toString())) {
n++;
}
}
System.out.println(n);
}
}

58539-连续最大和


https://www.nowcoder.com/practice/5a304c109a544aef9b583dce23f5f5db?tpId=85&&tqId=29858&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking
【题目解析】:一个数组有 N 个元素,求连续子数组的最大和。 例如:[-1,2,1],和最大的连续子数组为[2,1],其和为 3
本题是一个经典的动规问题,简称dp问题,但是不要害怕,这个问题是非常简单的dp问题,而且经常会考察,所以大家一定要把这个题做会。本题题意很简单,就是求哪一段的子数组的和最大。
【解题思路】:
dp[i] 就是以数组下标为 i 的数做为结尾的最大子序列和,注意是以 i 为结尾,比如说现在有一个数组{6,-3,-2,7,-15,1,2,2},dp[2]就是以-2为结尾的,那么显然dp[3]的最大值就是1咯(6,-3,-2),dp[3]要以7结尾那么以7结尾的子序列最大和就是8(6,-3,-2,7)。现在我们开始细细品一下上面这个递推式,求dp[i]的时候是不是有两种可能,要么就是像上面的dp[3]一样,dp[2]求出来是1了,再加上自己array[3]是最大的,那么还有一种可能就是说如果dp[2]我求出来是-100,那如果我也是dp[2]+array[3]的话是-93, 这时候dp[2]反而是累赘,最大就是自己(因为前面定义了必须以i为结尾,也就说必须以7结尾)。

状态方程式:

max( dp[ i ] ) = getMax( max( dp[ i -1 ] ) + arr[ i ] ,arr[ i ] )

import java.util.Scanner;
public class Main {
public static int GetMax(int a, int b){ //得到两个数的最大值
return (a) > (b) ? (a) : (b);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int size = sc.nextInt();
int[] array = new int[size];
for(int i = 0; i< size;i++) {
array[i] = sc.nextInt();
}
int sum = array[0];
int max = array[0];
for(int i = 1;i < size;i++) {
sum = GetMax(sum + array[i], array[i]); //状态方程
if (sum >= max)
max = sum;
}
System.out.println(max);
}
}

day6

题目ID:45840-不要二


链接:https://www.nowcoder.com/practice/1183548cd48446b38da501e58d5944eb?tpId=85&&tqId=29840&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking
【题目解析】:二货小易有一个W*H的网格盒子,网格的行编号为0~H-1,网格的列编号为0~W-1。每个格子至多可以放一块蛋糕,任意两块蛋糕的欧几里得距离不能等于2。
对于两个格子坐标(x1,y1),(x2,y2)的欧几里得距离为:
( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) 的算术平方根
小易想知道最多可以放多少块蛋糕在网格盒子里。

本题看起来很难,实际是一个中等难度的题。本题如果没记错,是一个往年网易的笔试题,大家可以看到大厂的题的难度。
本题的重点是要读懂题意,并且需要多读两遍,才能读懂,本题本质就是在二维数组中每个坐标去放蛋糕,一个坐标位置放了蛋糕,跟他欧几里得距离为2的位置不能放蛋糕,这个就是关键点。对于两个格子坐标(x1,y1),(x2,y2)的欧几里得距离为: ( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) 的算术平方根 。
也就是说:如果(x1,y1)放了蛋糕,则满足 ( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) == 4的(x2,y2)不能放蛋糕。
( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) == 4看起来是一个无解的表达式。
但是可以进行加法表达式分解:
1+3=4
3+1=4
2+2=4
0+4=4
4+0=4
仔细分析前三个表达式是不可能的,因为(x1-x2) * (x1-x2)表达式结果不能等于2或3。
也就是说( (x1-x2) * (x1-x2) 和(y1-y2) * (y1-y2) )两个表达式一个等于0,一个等于4.
可以看出:假设放蛋糕的位置是(x1,y1),则不能放蛋糕的位置(x2,y2),满足x1==x2,y1-y2==2或者x1-x2==2,y1==y2.

【解题思路】:
仔细读理解了上面的题目解读,本题就非常简单了,定义一个二维数组,resize开空间并初始化,每个位置初始化为0,表示当蛋糕,a[i][j]位置放蛋糕,则可以标记处a[i][j+2]和a[i+1][j]位置不能放蛋糕,遍历一遍二维数组,标记处不能放蛋糕的位置,统计也就统计出了当蛋糕的位置数。

mport java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int col = in.nextInt();
int row = in.nextInt();
int count = 0;
int[][] array = new int[row][col];
for(int i = 0;i < row;i++) {
for(int j = 0;j < col;j++) {
if(array[i][j] == 0) {
count++;
if(i+2 < row) {
array[i+2][j] = 1;
}
if(j+2 < col) {
array[i][j+2] = 1;
}
}
}
}
System.out.println(count);
}
}

23292-字符串转成整数


https://www.nowcoder.com/practice/1277c681251b4372bdef344468e4f26e?tpId=13&&tqId=11202&rp=6&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking
【题目解析】:将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 数值为 0 或者字符串不是一个合法的数值则返回 0
就是将字符串转为整数的实现,比较简单。
【解题思路】:
解题思路非常简单,就是上次计算的结果*10,相当于10进制进位,然后加当前位的值。
例如:“123”转换的结果是
sum=0
sum*10+1->1
sum*10+2->12
sum*10+3->123
本题的关键是要处理几个关键边界条件:
1. 空字符串
2. 正负号处理
3. 数字串中存在非法字符

public class Solution {
public int StrToInt(String str) {
char[] chs = str.toCharArray();
if(str.isEmpty())
return 0;
int symbol = 1;
if(chs[0] == '-'){ //处理负号
symbol = -1;
chs[0] = '0'; //这里是字符'0',不是0
} else if(chs[0] == '+'){ //处理正号
symbol = 1;
chs[0] = '0';
}
int sum = 0;
for(int i=0;i < chs.length;++i) {
if(chs[i] < '0' || chs[i] > '9') {
sum = 0;
break;
}
sum = sum *10 + chs[i] - '0';
}
return symbol * sum;
}
}

day7

题目ID:45846 --Fibonacci数列


链接:https://www.nowcoder.com/practice/18ecd0ecf5ef4fe9ba3f17f8d00d2d66?tpId=85&&tqId=2984
6&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking
【题目解析】:Fibonacci数列是这样定义的:
F[0] = 0
F[1] = 1
for each i ≥ 2: F[i] = F[i-1] + F[i-2]
因此,Fibonacci数列就形如:0, 1, 1, 2, 3, 5, 8, 13, ...,在Fibonacci数列中的数我们称为Fibonacci数。给你一个N,你想让其变为一个Fibonacci数,每一步你可以把当前数字X变为X-1或者X+1,现在给你一个数N求最少需要多少步可以变为Fibonacci数。
本题是对于Fibonacci数列的一个考察,Fibonacci数列的性质是第一项和第二项都为1,后面的项形成递归:
F(n) = F(n - 1) + F(n - 2)。
【解题思路】:
本题可以通过先找到距离N最近的两个Fibonacci数,这两个数分别取自距离N的最近的左边一个数L和右边一个数R,然后通过min(N - L, R - N)找到最小步数。

import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
int f1=0;
int f2=1;
while(n>f2){
int f3=f1+f2;
f1=f2;
f2=f3;
}
//当退出循环的时候 f2<n<=f3
int min=Math.min(n-f1,f2-n);
System.out.println(min);
}
}

题目ID:36939-合法括号序列判断


链接:https://www.nowcoder.com/practice/d8acfa0619814b2d98f12c071aef20d4?tpId=8&&tqId=11039&rp=1&ru=/activity/oj&qru=/ta/cracking-the-coding-interview/question-ranking
【题目解析】:给定一个字符串A和其长度n,请返回一个bool值代表它是否为一个合法的括号串(只能由括号组成)。
本题考查的是对栈的应用
【解题思路】:
用栈结构实现,栈中存放左括号,当遇到右括号之后,检查栈中是否有左括号,如果有则出栈,如果没有,则说明不匹配。

import java.util.*;
public class Parenthesis {
public boolean chkParenthesis(String A, int n) {
// write code here
if(n%2!=0){
return false;
}
Stack<Character> stack=new Stack<>();
for (char c:A.toCharArray()){
if(c=='('){
stack.push(c);
}else if(c==')'){
if(stack.isEmpty()){
return false;
}else if(stack.peek()=='('){
stack.pop();
}
}else{
return false;
}
}
return stack.isEmpty();
}
}

day8

题目ID:45844 --两种排序方法


链接:https://www.nowcoder.com/practice/839f681bf36c486fbcc5fcb977ffe432?tpId=85&&tqId=29844&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking

考拉有n个字符串字符串,任意两个字符串长度都是不同的。考拉最近学习到有两种字符串的排序方法: 1.根据字符串的字典序排序。例如:
"car" < "carriage" < "cats" < "doggies < "koala"
2.根据字符串的长度排序。例如:
"car" < "cats" < "koala" < "doggies" < "carriage"
考拉想知道自己的这些字符串排列顺序是否满足这两种排序方法,考拉要忙着吃树叶,所以需要你来帮忙验证。
【解题思路】:
思路很简单,将接收的字符串都放到String数组中,利用string的compareTo方法来按ascii比较字符串字典序排序,利用string的length方法来比较字符串的长度排序

import java.util.*;
import java.io.*;
public class Main{
public static void main()throws IOException{
BufferedReader re=new BufferedReader(new InputStreamReader(System.in));
int n=Integer.parseInt(re.readLine());
String[] str=new String[n];
for(int i=0;i<n;i++){
str[i]=re.readLine();
}
if(isSortZidian(str)&&isSortLength(str)){
System.out.println("both");
}else if(isSortZidian(str)){
System.out.println("lexicographically");
}else if(isSortLength(str)){
System.out.println("lengths");
}else{
System.out.println("none");
}
}
public static boolean isSortZidian(String[] str){
for(int i=0;i<str.length-1;i++){
if(str[i].compareTo(str[i+1])>0){
return false;
}
}
return true;
}
public static boolean isSortLength(String[] str){
for(int i=0;i<str.length-1;i++){
if(str[i].length()>str[i+1].length()){
return false;
}
}
return true;
}
}

题目ID:36932-求最小公倍数


链接:https://www.nowcoder.com/practice/22948c2cad484e0291350abad86136c3?tpId=37&&tqId=21331&rp=1&ru=/activity/oj&qru=/ta/huawei/question-ranking

正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求输入A和B的最小公倍数。
【解题思路】:
最小公倍数 = 两数之积除以最大公约数,这里使用碾转相除法进行最大公约数的求解:即a与b的最大公约数可以转化为a、b之间的余数为两者之间最小的数之间的公约数。所以对于输入的两个数进行连续求余,直到余数为0,求余的分母即为结果。

import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int m=sc.nextInt();
int n=sc.nextInt();
int mn=gdc(m,n);
System.out.println(m*n/mn);
}
public static int gdc(int m,int n){
int r;
if(m==n){
return m;
}
if(m<n){
int temp=m;
m=n;
n=temp;
}
while((r=m%n)>0){
m=n;
n=r; 
}
return n;
}
}

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值