1 Star 0 Fork 31

阿明 / Ebooks

forked from Java精选 / Ebooks 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
2021年数据结构与算法面试题大汇总附答案.md 17.68 KB
一键复制 编辑 原始数据 按行查看 历史

2021年数据结构与算法面试题大汇总附答案

全部面试题答案,更新日期:01月30日,直接下载吧!

下载链接:高清500+份面试题资料及电子书,累计 10000+ 页大厂面试题 PDF

数据结构与算法

题1:输入某年某月某日,判断这一天是这一年的第几天?

程序分析:以3月5日为例,应该先把前两个月的加起来,然后再加上5天即本月的第几天,特殊情况,闰年且输入月份大于3时需考虑多加一天。

程序代码如下:

package com.yoodb.util;

import java.util.GregorianCalendar;
import java.util.Scanner;

public class Demo04 {

  private static Scanner scan;

  public static void main(String[] args) {
    scan = new Scanner(System.in);
    System.out.println("输入年份:");
    int year = scan.nextInt();
    System.out.println("输入月份:");
    int month = scan.nextInt();
    System.out.println("输入日期:");
    int day = scan.nextInt();
    //判断是否是闰年,GregorianCalendar:判断年份是否是闰年的方法
    GregorianCalendar gre = new GregorianCalendar();
    boolean isLeapYear = gre.isLeapYear(year);//返回true:是闰年,false:不是闰年

    int ap = isLeapYear ? 29 : 28;//判断2月份的天数
    int days = 0;
    switch (month) {
    case 1:
      days = day;
      break;
    case 2:
      days = 31 + day;
      break;
    case 3:
      days = 31 + ap + day;
      break;
    case 4:
      days = 31 + ap + 31 + day;
      break;
    case 5:
      days = 31 + ap + 31 + 30 + day;
      break;
    case 6:
      days = 31 + ap + 31 + 30 + 31 + day;
      break;
    case 7:
      days = 31 + ap + 31 + 30 + 31 + 30 + day;
      break;
    case 8:
      days = 31 + ap + 31 + 30 + 31 + 30 + 31 + day;
      break;
    case 9:
      days = 31 + ap + 31 + 30 + 31 + 30 + 31 + 31 + day;
      break;
    case 10:
      days = 31 + ap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + day;
      break;
    case 11:
      days = 31 + ap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + day;
      break;
    case 12:
      days = 31 + ap + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30 + day;
      break;

    default:
      System.out.println("月份输入错误!");
      break;
    }
    System.out.println("这一天是这一年的第" + days + "天");
  }
}

运行结果如下:

输入年份:
2020
输入月份:
2
输入日期:
10
这一天是这一年的第41天

题2:什么是希尔排序?

希尔排序(Shell Sort)是DL.Shell在1959年提出的,是插入排序的一种,它是是直接插入排序算法的一种更高版本的改进版本。

其实质是一种分组排序。把数据分成几组,然后再进行组内插入排序,不断重复这样的分组过程,直到只比较相邻元素的最后一趟排序为止。

通俗的讲就是把记录按步长gap分组,对每组记录采用直接插入排序方法进行排序;随着步长逐渐减小,所分成的组包含的记录越来越多;当步长值减小到1时,整个数据合成一组,构成一组有序记录,完成排序。

题3:Java 中如何计算出 1000 以内的所有完数?

程序分析

完全数(Perfect number),又称完美数或完备数,是一些特殊的自然数。它所有的真因子(即除了自身以外的约数)的和(即因子函数),恰好等于它本身。如果一个数恰好等于它的因子之和,则称该数为“完全数”。第一个完全数是6,第二个完全数是28,第三个完全数是496,后面的完全数还有8128、33550336等等。

第一个完全数是6,它有约数1、2、3、6,除去它本身6外,其余3个数相加,1+2+3=6。

程序代码

package com.jingxuan.system;

public class Wanshu {
	public static void main(String[] args) {
		int s;
		for (int i = 1; i <= 1000; i++) {
			s = 0;
			for (int j = 1; j < i; j++)
				if (i % j == 0)
					s = s + j;
			if (s == i)
				System.out.println(i);
		}
	}
}

执行结果

6
28
496

题4:请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续判断第二个字母。

程序分析:

用情况语句比较好,如果第一个字母一样,则判断用情况语句或if语句判断第二个字母。

程序代码

import java.util.Scanner;

public class Demo12 {

	private static Scanner in;
	public static void main(String[] args) {
		char weekSecond;
		in = new Scanner(System.in);
		System.out.println("请输入星期的第一个字母:");
		String letter = in.next();
		if (letter.length() == 1) {
			char weekFirst = letter.charAt(0);
			switch (weekFirst) {
			case 'm':
			case 'M':
				System.out.println("星期一(Monday)");
				break;
			case 't':
			case 'T':
				System.out
						.print("由于星期二(Tuesday)与星期四(Thursday)均以字母T开头,故需输入第二个字母才能正确判断:");
				letter = in.next();
				if (letter.length() == 1) {
					weekSecond = letter.charAt(0);
					if (weekSecond == 'U' || weekSecond == 'u') {
						System.out.println("星期二(Tuesday)");
						break;
					} else if (weekSecond == 'H' || weekSecond == 'h') {
						System.out.println("星期四(Thursday)");
						break;
					} else {
						System.out.println("Error!");
						break;
					}
				} else {
					System.out.println("输入错误,只能输入一个字母,程序结束!");
					break;
				}
			case 'w':
			case 'W':
				System.out.println("星期三(Wednesday)");
				break;
			case 'f':
			case 'F':
				System.out.println("星期五(Friday)");
				break;
			case 's':
			case 'S':
				System.out

						.print("由于星期六(Saturday)与星期日(Sunday)均以字母S开头,故需输入第二个字母才能正确判断:");
				letter = in.next();
				if (letter.length() == 1) {
					weekSecond = letter.charAt(0);
					if (weekSecond == 'A' || weekSecond == 'a') {
						System.out.println("星期六(Saturday)");
						break;
					} else if (weekSecond == 'U' || weekSecond == 'u') {
						System.out.println("星期日(Sunday)");
						break;
					} else {
						System.out.println("Error!");
						break;
					}
				} else {
					System.out.println("输入错误,只能输入一个字母,程序结束!");
					break;
				}
			default:
				System.out.println("输入错误,不能识别的星期值第一个字母,程序结束!");
				break;
			}
		} else {
			System.out.println("输入错误,只能输入一个字母,程序结束!");
		}
	}
}

运行结果

请输入星期的第一个字母:
m
星期一(Monday)

题5:Java 中如何实现二分法算法?

时间复杂度

1)最坏情况查找最后一个元素(或者第一个元素)Master定理T(n)=T(n/2)+O(1)所以T(n)=O(logn)。

2)最好情况查找中间元素O(1)查找的元素即为中间元素(奇数长度数列的正中间,偶数长度数列的中间靠左的元素)。

空间复杂度

S(n)=n

分析

在有序的N个元素的数组中查找输进去的数据x值。算法如下:

1)确定查找范围front=0,end=N-1,计算中项mid=(front+end)/2。

2)若a[mid]=x或front>=end,则结束查找;否则,向下继续。

3)若a[mid]<x,说明待查找的元素值只可能在比中项元素大的范围内,则把mid+1的值赋给front,并重新计算mid,转去执行步骤2;若a[mid]>x,说明待查找的元素值只可能在比中项元素小的范围内,则把mid-1的值赋给end,并重新计算mid,转去执行步骤2。

实例

package com.jingxuan.system;

public class BinarySearch {
	public static void main(String[] args) {
		// 二分法查找
		int[] binaryNums = { 1, 6, 15, 18, 27, 50 };
		int findValue = 27; // 查找27值
		int binaryResult = binarySearch(binaryNums, 0, binaryNums.length - 1, findValue);
		System.out.println("元素第一次出现的位置(索引从0开始):" + binaryResult);
	}

	/**
	 * 二分查找,返回该值第一次出现的位置(下标从 0 开始)
	 * 
	 * @param nums      查询数组
	 * @param start     开始下标
	 * @param end       结束下标
	 * @param findValue 要查找的值
	 * @return int
	 */
	private static int binarySearch(int[] nums, int start, int end, int findValue) {
		if (start <= end) {
			// 中间位置
			int middle = (start + end) / 2;
			// 中间的值
			int middleValue = nums[middle];
			if (findValue == middleValue) {
				// 等于中值直接返回
				return middle;
			} else if (findValue < middleValue) {
				// 小于中值,在中值之前的数据中查找
				return binarySearch(nums, start, middle - 1, findValue);
			} else {
				// 大于中值,在中值之后的数据中查找
				return binarySearch(nums, middle + 1, end, findValue);
			}
		}
		return -1;
	}
}

执行结果如下:

元素第一次出现的位置(索引从0开始):4

题6:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?

程序分析:

兔子的规律为数列1,1,2,3,5,8,13,21....

具体分析如下:

f(1) = 1(第1个月有一对兔子)

f(2) = 1(第2个月还是一对兔子)

f(3) = 2(原来有一对兔子,第3个开始,每个月生一对兔子)

f(4) = 3(原来有两对兔子,有一对可以生育)

f(5) = 5(原来有3对兔子,第3个月出生的那对兔子也可以生育了,那么现在有两对兔子可以生育)

f(6) = 8(原来有5对兔子,第4个月出生的那对兔子也可以生育了,那么现在有3对兔子可以生育)

..............

由以上可以看出,第n个月兔子的对数为

f(n) = f(n - 1) + f(n - 2);

f(n-1)是上个月的兔子数量,是原来有的。

f(n-2)是可以生育的兔子数,即多出来的数量。第n-2个月开始后的第3个月是第n个月,此时第n-2个月时的兔子都可以生育了。Java精选公众号,回复“面试资料”领取免费面试题集。

程序代码

public class Demo01 {
    public static void main(String args[]) {
        for (int i = 1; i <= 20; i++)
            System.out.println(f(i) + " ");
    }
    public static int f(int x) {
        if (x == 1||x == 2)
            return 1;
        else
            return f(x - 1) + f(x - 2);
    }
}

public class Demo011 {
	public static void main(String args[]) {
		math math = new math();
		for (int i = 1; i <= 20; i++)
			System.out.println(math.f(i) + " ");
	}
}
/**

 * 内部类

 */

class math {
	public int f(int x) {
		if (x == 1 || x == 2)
			return 1;
		else
			return f(x - 1) + f(x - 2);
	}
}

运行结果

1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 

题7:猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。

程序分析:

采取逆向思维的方法,从后往前推断。

程序代码

public class Demo06 {
    public static void main(String[] args) {
        int sum = 1;
        for (int i = 0; i < 9; i++) {
            sum = (sum + 1) * 2;
        }
        System.out.println("第一天共摘"+sum);
    }
}

运行结果

第一天共摘1534

题8:Java 如何实现数组中整数按从小到大顺序输出?

程序分析:利用指针方法。

程序代码如下:

package com.jingxuan.system;

public class ArraysOrder {
	public static void main(String[] args) {
		int[] arrays = { 600, 56, 220, 122, 501 };
		for (int i = arrays.length; --i >= 0;) {
			for (int j = 0; j < i; j++) {
				if (arrays[j] > arrays[j + 1]) {
					int temp = arrays[j];
					arrays[j] = arrays[j + 1];
					arrays[j + 1] = temp;
				}
			}
		}
		for (int n = 0; n < arrays.length; n++)
			System.out.println(arrays[n]);
	}

}

运行结果如下:

56
122
220
501
600

题9:一个整数,它加上100后是一个完全平方数,加上168又是一个完全平方数,请问该数是多少?

程序分析:在10万以内判断,先将该数加上100后再开方,再将该数加上168后再开方,如果开方后的结果满足如下条件,即是结果。请看具体分析:

程序代码如下:

package com.yoodb.util;

public class Demo03 {

  public static void main(String[] args) {
    for (int i = 1; i < 1000; i++) {
      int m = (int) Math.sqrt((i + 100));
      int n = (int) Math.sqrt((i + 100 + 168));
      if (m * m == i + 100 && n * n == i + 100 + 168) {
        System.out.println("这个数是" + i);
      }
    }
  }
}

运行结果如下:

这个数是21
这个数是261

题10:有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。

程序分析:

首先随机生成一个混乱的数组,通过判断每个数是否大于最后一个数,然后再考虑插入中间的数的情况,插入后此元素之后的数,依次后移一个位置。

程序代码

import java.util.Random;

public class Demo16 {

	public static void main(String[] args) {
		int temp = 0;
		int arr[] = new int[12];
		Random r = new Random();
		for (int i = 0; i <= 10; i++)
			arr[i] = r.nextInt(1000);
		for (int i = 0; i <= 10; i++)
			System.out.print(arr[i] + "\t");
		for (int i = 0; i <= 9; i++)
			for (int k = i + 1; k <= 10; k++)
				if (arr[i] > arr[k]) {
					temp = arr[i];
					arr[i] = arr[k];
					arr[k] = temp;
				}
		System.out.println();
		for (int k = 0; k <= 10; k++)
			System.out.print(arr[k] + "\t");
		arr[11] = r.nextInt(1000);
		for (int k = 0; k <= 10; k++)
			if (arr[k] > arr[11]) {
				temp = arr[11];
				for (int j = 11; j >= k + 1; j--)
					arr[j] = arr[j - 1];
				arr[k] = temp;
			}
		System.out.println();
		for (int k = 0; k <= 11; k++)
			System.out.print(arr[k] + "\t");
	}
}

运行结果

265	882	280	873	848	283	423	549	569	494	52	
52	265	280	283	423	494	549	569	848	873	882	
52	265	280	283	423	494	549	569	701	848	873	882

题11:海滩上有一堆桃子五只猴子来分。第一只猴子把这堆桃子凭据分为五份多了一个这只猴子把多的一个扔入海中拿走了一份。第二只猴子把剩下-的桃子又平均分成五份又多了一个它同样把多的一个扔入海中拿走了一份第三第四第五只猴子都是这样做的问海滩上原来最少有多少个桃子

题12:判断-0-100-之间有多少个素数并输出所有素数。-

题13:如何取一个整数中从右端开始的4~7位的数字--

题14:什么是平衡二叉树

题15:二叉树基本概念是什么

题16:一球从100米高度自由落下每次落地后反跳回原高度的一半;再落下求它在---第10次落地时共经过多少米第10次反弹多高-

题17:在排序数组中如何查找元素的第一位和末尾位置

题18:输入三个整数x,y,z请把这三个数由小到大输出。

题19:java-中实现斐波那契数列有哪些方法

题20:java-中如何编写一个希尔排序算法

题21:java-中如何将一个数组逆序输出

题22:什么是数据结构

题23:求数组中某个数字出现的次数

题24:说说几种常见的排序算法和复杂度

题25:有一分数序列-2/13/25/38/513/821/13...求出这个数列的前20项之和。-

大厂面试题

大厂面试题

大厂面试题

Java
1
https://gitee.com/AminDev/ebooks.git
git@gitee.com:AminDev/ebooks.git
AminDev
ebooks
Ebooks
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891