1 Star 0 Fork 31

邪恶的笨笨熊 / Ebooks

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

数据结构与算法面试题汇总附答案,2021年最新整合版

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

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

数据结构与算法

题1:Java 中如何将一个数组逆序输出?

程序分析:循环遍历从后往前取数组长度减1作为数的索引值,然后输出其数据。

程序代码如下:

package com.jingxuan.system;

public class ArraysReverse {
	public static void main(String[] args) {
		int[] n = { 61, 62, 21, 34, 25, 82 };
		System.out.println("数组逆序输出为");
		for (int i = n.length; i > 0; i--) {
			System.out.print(n[i-1] +  " ");
		}
	}
}

运行结果如下:

数组逆序输出为
82 25 34 21 62 61 

题2:如何实现数组中最大与第一个元素交换,最小与最后一个元素交换并输出数组?

程序代码如下:

package com.jingxuan.system;

public class ArraysZDY {
	public static void main(String[] args) {
		int i, min, max, temp1, temp2;
		int a[] = {92,12,33,83,68,54};
		max = 0;
		min = 0;
		for (i = 1; i < a.length; i++) {
			if (a[i] > a[max])
				max = i;
			if (a[i] < a[min])
				min = i;
		}
		temp1 = a[0];
		temp2 = a[min];

		a[0] = a[max];
		a[max] = temp1;

		if (min != 0) {
			a[min] = a[a.length - 1];
			a[a.length - 1] = temp2;
		} else {
			a[max] = a[a.length - 1];
			a[a.length - 1] = temp1;
		}

		for (i = 0; i < a.length; i++) {
			System.out.print(a[i] + " ");
		}
	}
}

运行结果如下:

92 54 33 83 68 12 

题3:什么是树?

树是一种重要的非线性数据结构,它是数据元素(在树中称为结点)按分支关系组织起来的结构,类似自然界中的真实的树。

树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树形象表示。

树在计算机领域中也得到广泛应用,如在编译源程序时,可用树表示源程序的语法结构。又如在数据库系统中,树型结构也是信息的重要组织形式之一。一切具有层次关系的问题都可用树来描述。

树是由一个或多个结点组成的有限集合:

1)必有一个特定的称为根(ROOT)的结点;

2)剩下的结点被分成n>=0个互不相交的集合T1、T2、......Tn,而且, 这些集合的每一个又都是树。树T1、T2、......Tn被称作根的子树(Subtree)。

树的递归定义如下:

1、至少有一个结点,称为根;

2、其它是互不相交的子树。

树结构的特点是每一个结点都可以有不止一个直接后继,除根结点外的所有结点都有且只有一个直接前趋。

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

程序源码

import java.util.Scanner;

public class Tests {

	public static void main(String[] args) {
		int a, b, num1, num2, temp;
		System.out.println("请你输入需要计算的两个数字:\n");
		Scanner sc = new Scanner(System.in);
		num1 = sc.nextInt();
		num2 = sc.nextInt();
		if (num1 < num2)/* 交换两个数,使大数放在num1上 */
		{
			temp = num1;
			num1 = num2;
			num2 = temp;
		}
		a = num1;
		b = num2;
		//辗转相除法一般指欧几里得算法
		while (b != 0)/* 利用辗除法,直到b为0为止 */
		{
			temp = a % b;
			a = b;
			b = temp;
		}
		System.out.println("公约数" + a);
		System.out.println("公倍数" + num1 * num2 / a);
	}
}

输出结果

请你输入需要计算的两个数字:

65
78
公约数13
公倍数390

题5:树和二叉树有什么区别和联系?

1、两者性质不同

树是一种数据结构;二叉树是每个结点最多有两个子树的一种树结构。

2、结点数目不同

树的每个结点有零个或多个子结点;没有父结点的结点称为根结点;每一个非根结点有且只有一个父结点。而二叉树的每个结点最多有两个子树。

树和二叉树的联系:树都可用二叉链表作为存储结构,对比各自的结点结构可以看出,以二叉链表作为媒介可以导出树和二叉树之间的一个对应关系。

从物理结构来说,树和二叉树的二叉链表是相同的,只是对指针的逻辑解释不同而已。从树的二叉链表表示的定义而言,任何一棵和树对应的二叉树,其右子树一定为空。

1)树中结点的最大度数没有限制,而二叉树结点的最大度数为2;

2)树的结点无左、右之分,而二叉树的结点有左、右之分。

题6:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。

程序分析:程序分析:假设有5个人,围成一圈,顺序排号,报数1、2、3、1、2,分别对应a、b、c、d、e;剩下a、b、d、e,继续报数3、1、2、3;剩下b、d,继续报数1、2,没有退出圈子的人,继续报数3、1;剩下d,最后留下来的是第4位。

程序代码如下:

package com.jingxuan.system;

import java.util.Scanner;

public class LeaveH {

	private static Scanner s;

	public static void main(String[] args) {
		System.out.print("请输入有几个人参加:");
		s = new Scanner(System.in);
		int n = s.nextInt();
		boolean[] arr = new boolean[n];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = true;
		}
		int leftCount = n;
		int countNum = 0;
		int index = 0;
		while (leftCount > 1) {
			if (arr[index] == true) {
				countNum++;
				if (countNum == 3) {
					countNum = 0;
					arr[index] = false;
					leftCount--;
				}
			}
			index++;
			if (index == n) {
				index = 0;
			}
		}
		for (int i = 0; i < n; i++) {
			if (arr[i] == true) {
				System.out.println( "最后留下的是原来第" + (i+1) + "号");
			}
		}
	}
}

运行结果如下:

请输入有几个人参加:5
最后留下的是原来第4号

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

程序分析:以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天

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

程序分析:

我们想办法把最小的数放到x上,先将x与y进行比较,如果x>y则将x与y的值进行交换,然后再用x与z进行比较,如果x>z则将x与z的值进行交换,这样能使x最小。

程序代码

import java.util.Arrays;
import java.util.Scanner;

public class Demo05 {
    private static Scanner in;

	public static void main(String[] args) {
        System.out.println("请输入三个数:");
        in = new Scanner(System.in);
        int[] arr = new int[3];
        for (int i = 0; i < 3; i++) {
            arr[i] = in.nextInt();
        }
        Arrays.sort(arr);
        for (int i=0;i<arr.length;i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

import java.util.Scanner;

public class Demo051 {

	private static Scanner in;

	public static void main(String[] args) {
		System.out.println("请输入三个数:");
		in = new Scanner(System.in);
		int[] arr = new int[3];
		for (int i = 0; i < 3; i++) {
			arr[i] = in.nextInt();
		}

		int x = arr[0], y = arr[1], z = arr[2];
		if (x > y) {
			int t = x;
			x = y;
			y = t;
		}

		if (x > z) {
			int t = x;
			x = z;
			z = t;
		}

		if (y > z) {
			int t = y;
			y = z;
			z = t;
		}
		System.out.print(x + " " + y + " " + z);
	}
}

运行结果

请输入三个数:
4
8
6
4 6 8 

题9:三个字符串如何验证其中字符串由另外两个字符串交错组成?

假设三个字符串s1、s2、s3,验证s3是否是由s1和s2交错组成的。注意是s1与s2交错组成s2字符串。

两个字符串s和t交错的定义与过程如下,其中每个字符串都会被分割成若干非空子字符串:

s=s1+s2+...+sn
t=t1+t2+...+tm
|n-m|<=1

交错是s1+t1+s2+t2+s3+t3+...或者t1+s1+t2+s2+t3+s3+...

提示:a+b意味着字符串a和b连接。

示例1

输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
输出: true

示例2

输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
输出: false

程序代码

class Solution {

	public static void main(String[] args) {
		String s1 = "ab", s2 = "cd", s3 = "acbd";
		System.out.println(isInterleave(s1, s2, s3));
	}

	public static boolean isInterleave(String s1, String s2, String s3) {
		if ((s1.length() + s2.length()) != s3.length())
			return false;

		boolean[][] dp = new boolean[s2.length() + 1][s1.length() + 1];

		dp[0][0] = true;
		for (int i = 1; i <= s1.length(); i++) {
			dp[0][i] = dp[0][i - 1] && s1.charAt(i - 1) == s3.charAt(i - 1) ? true : false;
		}

		for (int i = 1; i <= s2.length(); i++) {
			dp[i][0] = dp[i - 1][0] && s2.charAt(i - 1) == s3.charAt(i - 1) ? true : false;
		}

		for (int i = 1; i < dp.length; i++) {
			for (int j = 1; j < dp[0].length; j++) {
				dp[i][j] = (dp[i][j - 1] && s1.charAt(j - 1) == s3.charAt(i + j - 1))
						|| (dp[i - 1][j] && s2.charAt(i - 1) == s3.charAt(i + j - 1));
			}
		}
		return dp[s2.length()][s1.length()];
	}
}

运行结果

true

题10:Java 如何实现链表归并排序?

归并排序可以说是链表排序中最佳的选择,能够保证最好和最坏时间复杂度都是nlogn,而且在数组排序中广受开发人反感的空间复杂度在链表排序中也从O(n)降到了O(1)。

归并排序的一般分为四步:

1)将需要排序数组(链表)取中点并一分为二,拆分为两个链表:head和second两个子链表;

2)使用递归方式对左半部分子链表进行归并排序;

3)使用递归方式对右半部分子链表进行归并排序;

4)将两个半部分子链表进行合并(merge),得到结果。

首先用快慢指针(快慢指针思路,快指针一次走两步,慢指针一次走一步,快指针在链表末尾时,慢指针恰好在链表中点)的方法找到链表中间节点,然后使用递归对两个子链表排序,把两个排好序的子链表合并成一条有序的链表。

程序代码,为了方便输出查看结果,使用Gson包,不需要可以去除相关代码:

import com.google.gson.Gson;

class ListNode {
	int val;
	ListNode next;

	ListNode(int x) {
		val = x;
		next = null;
	}
}

public class LinkedInsertSort {

	/**
	 * @author 公众号:Java精选
	 * @param args
	 */
	public static void main(String[] args) {
		ListNode node = new ListNode(4);
		node.next = new ListNode(3);
		LinkedInsertSort lss = new LinkedInsertSort();
		System.out.println(new Gson().toJson(lss.mergeSort(node)));
	}

	public ListNode mergeSort(ListNode head) {
		if (head == null || head.next == null)
			return head;

		ListNode mid = getMid(head);// 获取链表中间节点

		// 把链表从之间拆分为两个链表:head和second两个子链表
		ListNode second = mid.next;
		mid.next = null;

		// 对两个子链表排序
		ListNode left = mergeSort(head);
		ListNode right = mergeSort(second);

		return merge(right, left);
	}

	// 两个有序链表的归并
	private ListNode merge(ListNode l1, ListNode l2) {
		// 辅助节点,排好序的节点将会链接到dummy后面
		ListNode dummy = new ListNode(0);

		ListNode tail = dummy;// tail指向最后一个排好序的节点
		while (l1 != null && l2 != null) {
			if (l1.val <= l2.val) {
				tail.next = l1;
				l1 = l1.next;
			} else {
				tail.next = l2;
				l2 = l2.next;
			}
			tail = tail.next; // 移动tail指针
		}

		if (l1 != null)
			tail.next = l1;
		else
			tail.next = l2;

		return dummy.next;

	}

	// 返回链表之间节点
	private ListNode getMid(ListNode head) {
		if (head == null || head.next == null)
			return head;

		ListNode slow = head;
		ListNode faster = head.next;
		while (faster != null && faster.next != null) {
			slow = slow.next;
			faster = faster.next.next;
		}
		return slow;
	}
}

输出结果

{"val":3,"next":{"val":4}}

题11:打印出如下图案菱形

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

题13:什么是平衡二叉树

题14:什么是二分法使用时注意事项

题15:写一个函数求一个字符串的长度在main函数中输入字符串并输出其长度。

题16:什么是数据结构

题17:有5个人坐在一起问第五个人多少岁他说比第4个人大2岁。问第4个人岁数他说比第3个人大2岁。问第三个人又说比第2人大两岁。问第2个人说比第一个人大两岁。最后问第一个人他说是10岁。请问第五个人多大

题18:求一个3*3矩阵主对角线元素之和。

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

题20:将一个正整数分解质因数。例如-输入90,打印出90=233*5。

题21:有n个整数使其前面各数顺序向后移m个位置最后m个数变成最前面的m个数-

题22:什么是斐波那契数列

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

题24:编写一个函数输入n为偶数时调用函数求1/21/4...1/n,当输入n为奇数时调用函数1/11/3...1/n

题25:java-中如何实现杨辉三角形

大厂面试题

大厂面试题

大厂面试题

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

搜索帮助

53164aa7 5694891 3bd8fe86 5694891