Java算法面试题


题目1:一个数组,让数组的每个元素去除第一个元素,得到的商作为被除数所在位置的新值。

 1     @Test
 2     public void test1() {
 3         int[] array = new int[] { 3, -10, 22, 19, 21, 9, -89 };
 4 
 5         for (int i = array.length - 1; i >= 0; i--) {
 6             array[i] = array[i] / array[0];
 7         }
 8 
 9         for (int i = 0; i < array.length; i++) {
10             System.out.print(array[i] + " ");
11         }
12 
13     }
View Code

注: 这道题的"陷进"在于如果循环是从数组的第一位元素开始的, 那么经过第一次计算之后,第一位元素的值将变成"1", 那么后面的元素的值都不会再变化. 如果是从数组的末尾开始遍历将不会有这个问题.

 

 

题2: 输入两个正整数m和n,求其最大公约数和最小公倍数。

 1     @Test
 2     public void test2() {
 3         int m = 12;
 4         int n = 28;
 5 
 6         int max = (m > n) ? m : n;
 7         int min = (m > n) ? n : m;
 8 
 9         for (int i = min; i >= 1; i--) {
10             if (max % i == 0 && min % i == 0) {
11                 System.out.println("m和n的最大公约数是: " + i);
12                 break;
13             }
14         }
15 
16         for (int i = max; i < m * n; i++) {
17             if (i % m == 0 && i % n == 0) {
18                 System.out.println("m和n的最小公倍数是: " + i);
19                 break;
20             }
21         }
22 
23     }
View Code

 

 

题目3:输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。


例如:输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,因此输出为该子数组的和18。

分析:如果不考虑时间复杂度,我们可以枚举出所有子数组并求出他们的和。不过非常遗憾的是,由于长度为n的数组有O(n^2)个子数组;而且求一个长度为n的数组的和的时间复杂度为O(n)。因此这种思路的时间是O(n^3)。

 1     @Test
 2     public void test3() {
 3         int[] array = new int[] { 1, -2, 3, 10, -4, 7, 2, -5 };
 4 
 5         int maxSum = 0;
 6         int temp = maxSum;
 7         for (int i = 0; i < array.length; i++) {
 8             temp += array[i];
 9 
10             /*
11              *  因为数组有正数,也有负数, 如果元素之和小于0,
12              *  那么需要丢弃这两个元素,即把temp置为0.
13              */
14             if (temp < 0) {
15                 temp = 0;
16             }
17 
18             // 如果temp的值比之前的最大和还大,那么需要提升maxSum的值
19             if (temp > maxSum) {
20                 maxSum = temp;
21             }
22 
23             /*
24              * 最极端的情况: 如果正数后面的那个元素总是负数,而且加起来值总是小于0, 
25              * 那么最大和就是数组中值最大的那个元素
26              */
27             if (maxSum == 0) {
28                 for (i = 0; i < array.length; i++) {
29                     if (array[i] > maxSum) {
30 
31                         maxSum = array[i];
32                     }
33                 }
34             }
35 
36         }
37 
38         System.out.println("所有子数组的最大值为: " + maxSum);
39     }
View Code

 

 

题目4: 将一个字符串进行反转。将字符串中指定部分进行反转。比如将“abcdefg”反转为”abfedcg”。

 1 public class test {
 2         
 3     /*
 4     * 将一个字符串进行反转。将字符串中指定部分进行反转,
 5         * 比如将“abcdefg”反转为”abfedcg”
 6     */
 7     
 8     public static void main(String [] args){
 9         String str = "abcdefg";
10                 
11         String newStr = reverseString(str,3,6);
12         System.out.println("Reverse string is: " + newStr);
13     }
14         
15     public static String reverseString(String str, int start,int end){
16         char [] c = str.toCharArray();
17         char temp ;
18 
19         for(int x = start -1, y = end -1; x < y ; x++,y--){
20             temp = c[x];
21             c[x] = c[y];
22             c[y] = temp;
23         }
24             
25         return new String(c);
26     }
27     
28 
29 }
View Code

 

 

题目5: 输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。

例如输入“I am a student.”,则输出“student. a am I”。

 1 /*
 2  * 输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。
 3  * 句子中单词以空格符隔开。为简单起见,标点符号和普通字母一样处理。
 4  * 例如输入“I am a student.”,则输出“student. a am I”。
 5  */
 6 
 7 public class Test {
 8     public static void main(String[] args) {
 9         String str = "I am a student.";
10         
11         String newStr = wordReverse(str);
12         
13         System.out.println("Reverse String is: " + newStr);
14     }
15     
16     public static String wordReverse(String str){
17         String [] s = str.split(" ");
18         String temp;
19         for(int x =0,y=s.length-1;x<y;x++,y--){
20             temp = s[x];
21             s[x] = s[y];
22             s[y] = temp;
23         }
24         
25         String newStr= "";
26         for(int i =0;i<s.length;i++){
27             newStr += s[i]+ " ";
28         }
29         
30         return newStr.trim();
31     }
32 }
View Code

 

题目6: 获取两个字符串中最大相同子串。比如:str1 = "abcwerthelloyuiodef“;str2 = "cvhellobnm"

提示:将短的那个串进行长度依次递减的子串与较长的串比较。

 1 public class Test {
 2     public static void main(String[] args) {
 3         String str1 = "abcwerthelloyuiodef";
 4         String str2 = "cvhellobnm";
 5         
 6         String newStr = getMaxSubstring(str1,str2);
 7         
 8         System.out.println("The max Substring is: " + newStr);
 9     }
10 
11     private static String getMaxSubstring(String str1, String str2) {
12         int len1 = str1.length();
13         int len2 = str2.length();
14         
15         String maxStr = (len1> len2)? str1:str2;
16         String minStr = (len1> len2)? str2: str1;
17         
18         int len = minStr.length();
19         String tempStr = "";
20         
21         for(int i = len; i>0;i--){
22             for(int j = 0; j <= len - i; j++){
23                 tempStr = minStr.substring(j, j+i);
24                  if(maxStr.contains(tempStr)){
25                      return tempStr;             
26                  }
27             }
28         }
29         
30         return null;
31     }
32 }
View Code

 

题目7: 已知有一个数列:f(0) = 1,f(1) = 4,f(n+2)=2*f(n+1) + f(n),其中n是大于0的整数,求f(10)的值。

提示: 递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。

 1 /*
 2  * 已知有一个数列:f(0) = 1,f(1) = 4,f(n+2)=2*f(n+1) + f(n),
 3  * 其中n是大于0的整数,求f(10)的值。
 4  */
 5 
 6 public class Test {
 7     public static void main(String[] args) {
 8         int i = 2;
 9         int result = func(i);
10 
11         System.out.println("The result is: " + result);
12     }
13 
14     private static int func(int n) {
15         int temp;
16         if (n == 0) {
17             temp = 1;
18         } else if (n == 1) {
19             temp = 4;
20         } else {
21             temp = 2 * func(n - 1) + func(n - 2);
22         }
23 
24         return temp;
25     }
26 
27 }
View Code

 

题目8: for循环的基础,下面的输出结果是什么?

1     @Test
2     public void test4(){
3         
4         int i = 0;
5         for(i++;i++<10;i++);
6         System.out.println("最后i的值为:" + ++i);
7     }
View Code

注意: for循环没有循环体.

分析过程:
for循环的基本格式for(A;B;C){}

首先执行A,并且A只执行一次(这个地方容易出错),然后执行B,符合条件就执行循环体,若不存在循环体就直接执行B;不符合条件就直接跳出循环体。

对于这个题目:
首先要明白++i和i++的区别:i++,在执行完后i=i+1;++i,在执行前i=i+1对于这个循环可以这样写for(i=i+1;i<10,i=i+1;i++)开始i=0;

第一次循环:i++;则判断条件是1<10,i=i+1;成立,执行循环体(若加一个输出语句System.out.println(i)则为2),循环体不存在,执行i=i+1此时i为3;

第二次循环:判;断条件是3<10,i=i+1;成立,执行循环体(若加一个输出语句System.out.println(i)则为4),循环体不存在,执行i=i+1此时i为5

第三次循环:则判断条件是5<10,i=i+1;成立,执行循环体(若加一个输出语句System.out.println(i)则为6),循环体不存在,执行i=i+1此时i为7;

第四次循环:则判断条件是7<10,i=i+1;成立,执行循环体(若加一个输出语句System.out.println(i)则为8),循环体不存在,执行i=i+1此时i为9;

第五次循环:则判断条件是9<10,i=i+1;成立,执行循环体(若加一个输出语句System.out.println(i)则为10),循环体不存在,执行i=i+1此时i为11;

第六次循环:则判断条件是11<10,i=i+1;不成立,跳出循环,此时i为12外面的输出语句System.out.println(++i);等价于:i=i+1;System.out.println(i); 因此输出的是13.

posted @ 2017-04-23 11:24  fengze  阅读(262)  评论(0编辑  收藏  举报