JAVA程序员必须掌握的数据结构的面试题(附答案)

常见的数据结构

  1. 数组
  2. 队列
  3. 链表
  4. 字典树(高效树形结构)
  5. 散列表(哈希表)

一. 数组

1.寻找数组中第二大的元素

	//冒泡排序法
	public static void getMethod_1(int[] array){
		int temp = 0;
		int len = array.length;
		for(int i = 0;i<len;i++){
			if(i == len-1){
				break;
			}
			for(int j = i+1;j<len;j++){
				if(array[i]>=array[j])
					continue;
				else{
					temp = array[j];
					array[j] = array[i];
					array[i] = temp;
				}
			}
		}
		System.out.println(array[1]);
	}
	public static void main(String[] args) {
		getMethod_1(new int[]{1,2,3,9,8,7,5,6,-1,-2,-3,-9,-8,-7,-5,-6});
	}

2.寻找数组中不重复出现的整数

	//有且只有一个数字不重复
	public static int getMethod_2(int[] array){
		int len = array.length;
		int res = -1;
		if(len>1){
			res = array[0];
			for(int i = 1;i<len;i++){
				res = res^array[i];
			}
		}
		return res;
	}
	
	//有多个不重复数字,找出所有不重复数字
	public static ArrayList<Integer> getMethod_3(int[] array){
		ArrayList<Integer> res = new ArrayList<Integer>();
		if(array==null||array.length<2)
			return res;
		Map<Integer,Integer> map = new LinkedHashMap<>();
		for(int i = 0;i<array.length;i++){
			if(map.containsKey(array[i]))
				map.put(array[i],map.get(array[i])+1);
			else
				map.put(array[i], 1);	
		}
		for(Integer key : map.keySet()){
        	if(map.get(key) == 1)
        		res.add(key);
        }
		return res;
	}
	
	//寻找数组中第一个不重复出现的字符
	public static char findFirst(String str) {
		if (str == null || str.length() == 0)
			return '#';
		int[] hashtable = new int[256];
		int len = str.length();
		char[] arr = str.toCharArray();
		for (int i = 0; i < len; i++) {
			hashtable[arr[i]]++;
		}
		for (int i = 0; i < len; i++) {
			if (hashtable[arr[i]] == 1)
				return arr[i];
		}
		return '#';
	}

	public static void main(String[] args) {
		//不重复的数字只有一个,找到这个数
		int number = getMethod_2(new int[]{1,1,1,1,1,1,1,1,1,-2,1,1,1});
		System.out.println(number);
		//寻找数组中第一个不重复出现的整数
		ArrayList<Integer> number_3 = getMethod_3(new int[]{8,7,5,6,-1,-2,-3,-9,-8,-7,-5,-6,1,2,3,9,8});
		System.out.println(number_3.size()>0?number_3.get(0):"没有找到不重复数字");
	}

3.实现数组中负数在左,正数在右

	/**
	 * 方式一
	 * 实现原理是:两个变量记录左右节点,两边分别开始遍历。左边的节点遇到负值继续前进,遇到正值停止。右边的节点正好相反。   
	 * 然后将左右节点的只进行交换,然后再开始遍历直至左右节点相遇。  
	 * 这种方式的时间复杂度是O(n).空间复杂度为O(1)
	 * @param a		要排列数组
	 * @param left	左开始索引
	 * @param right	右开始索引
	 */
	public static void setParted1(int[] a, int left, int right) {
		if (left >= right || left == a.length || right == 0) {
			for (int i = 0; i < a.length; i++) {
				System.out.println(a[i]);
			}
			return;
		}
		while (a[left] < 0) {
			left++;
		}
		while (a[right] >= 0) {
			right--;
		}
		if (left >= right || left == a.length || right == 0) {
			for (int i = 0; i < a.length; i++) {
				System.out.print(a[i]+"\t");
			}
			System.out.println();
			return;
		}
		swap(a, left, right);
		left++;
		right--;
		setParted1(a, left, right);
	}

	private static void swap(int a[], int left, int right) {
		int temp = 0;
		temp = a[left];
		a[left] = a[right];
		a[right] = temp;
	}

	/**
	 * 方式二
	 */
	public static void setParted(int[] a) {
		int temp = 0;
		int border = -1;

		for (int i = 0; i < a.length; i++) {
			if (a[i] < 0) {
				temp = a[i];
				a[i] = a[border + 1];
				a[border + 1] = temp;
				border++;
			}
		}
		for (int j = 0; j < a.length; j++) {
			System.out.print(a[j]+"\t");
		}
		System.out.println();
	}

	public static void main(String[] args) {
		int a[] = { 1, 2, -1, -5, -6, 7, -7, -10 };
		int b[] = {8,7,-1,-2,-3,-9,-8,-7,2,3,9,8};
		setParted(a);
		setParted1(b,0,b.length-1);
	}

二. 栈

1.用栈计算后缀表达式

	private static final char ADD = '+';
	private static final char SUB = '-';
	private static final char MUL = '*';
	private static final char DIV = '/';
	private static Stack<Integer> stack = new Stack<Integer>();
	/**
	 * 后缀表达式就是:操作符位于两个操作数之后,后缀表达式的形式如下:<操作数><操作数><操作符>
	 * 中缀表达式就是:操作符位于操作数之间。中缀表达式的形式如下:<操作数><操作符><操作数>
	 */
	public static int evaluate(String expr){
		// 将字符串分解,\s 匹配任何空白字符,包括空格、制表符、换页符等。
		String[] tokenizer = expr.split("\\s");// 
		for(int i = 0;i<tokenizer.length;i++){
			String token = tokenizer[i].trim();
			if(isOperator(token)){	// 判断是操作符,则出栈两个操作数
				int op2 = stack.pop().intValue();
				int op1 = stack.pop().intValue();
				char operator = token.charAt(0);
				stack.push(calc(operator,op1,op2));
			}else{
				stack.push(Integer.parseInt(token));
			}
		}
		
		return stack.pop();	// 将最后的计算结果返回
	}

	private static Integer calc(char operation, int op1, int op2) {
		int result = 0;
		switch (operation) {
		case ADD:
			result = op1 + op2;
			break;
		case SUB:
			result = op1 - op2;
			break;
		case MUL:
			result = op1 * op2;
			break;
		case DIV:
			result = op1 / op2;
			break;
		}
		return result;

	}

	private static boolean isOperator(String token) {
		return (token.equals("+") || token.equals("-") || token.equals("*") || token
				.equals("/"));
	}
	
	public static void main(String[] args) {
		String expression = "3 2 2 * + 1 -";
		int result = evaluate(expression);
		System.out.println("计算结果为:" + result);
	}

2.对栈数据进行排序

	//双栈排序
	public Stack<Integer> twoStackSort(Stack<Integer> s){
		Stack<Integer> stack = new Stack<Integer>();
		while(!s.isEmpty()){
			int tmp = s.pop();
			while(!stack.isEmpty() && stack.peek() > tmp){
				s.push(stack.pop());
			}
			stack.push(tmp);
		}
		return stack;
	}

	public static void main(String[] args) {
		Stack<Integer> stack = new Stack<Integer>();
		stack.push(5);
		stack.push(4);
		stack.push(7);
		stack.push(8);
		stack.push(6);
		stack.push(1);
		stack.push(9);
		stack.push(2);
		stack.push(3);
		Stack<Integer> stack2 = twoStackSort(stack);
		System.out.println(stack2);
	}

2.用栈来判断括号匹配问题

	public static boolean isValidate(String s){
		Stack<Character> a = new Stack<Character>();
		for(int i = 0 ;i<s.length();i++){
			char c = s.charAt(i);
			if(c=='(')
				a.push(')');
			if(c=='[')
				a.push(']');
			if(c=='{')
				a.push('}');
			if(c == ')' || c == ']' || c == '}'){
				if(a.size()==0)
					return false;
				if(a.pop()!=c)
					return false;
			}
		}
		if(a.size()!=0)
			return false;
		return true;
	}

	public static void main(String[] args) {
		//判断括号匹配问题
		String s = "..(..(..[]..)..)";
		boolean a = isValidate(s);
		System.out.println(a);
	}

三. 队列

  • 8
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值