数据结构面试题
数组
1.寻找数组中第二小的元素
方法1:递增排序,从前面开始选择,并不一定是第二个;
public static void main(String[] args) { int arr[]={34,12,23,90,12,-87,-27}; Arrays.sort(arr); //排序 升序 int secondNum=arr[0]; for(int i=1;i<arr.length;i++){ if(arr[0]<arr[i]){ secondNum=arr[i]; break; } } System.out.println(secondNum); }
方法2:遍历数组两次,第一次找到最小的,让这个元素为x,在第二次遍历中,找到最小的元素大于x
方法3:在一次遍历中找到最小的两个数
public static void main(String[] args) { int arr[]={-87,-97,23,90,12,-87,-87}; int firstmin = Integer.MAX_VALUE; //第一小的元素 初始值设为int的最大取值 int secondmin = Integer.MAX_VALUE; //第二小的元素 初始值设为int的最大取值 for(int value:arr){ if (value < firstmin) //小于最小的元素 更新1和2 { secondmin = firstmin; firstmin = value; } else if (value < secondmin && value != firstmin) //小于倒数二的 更新2 { secondmin = value; } } System.out.println("firstmin--------->"+firstmin); System.out.println("secondmin--------->"+secondmin); }
2.合并两个有序数组
方法1:新构造一个空数组array3,那array2中的最前面的元素跟array1中的最前面的元素比较,然后将小的数依次插入到array3后面。这个方法降低了时间复杂度,但是额外构造了一个数组。
方法2:提示中已经给出,假设array1有足够的空间了,于是我们不需要额外构造一个数组,并且可以从后面不断地比较元素进行合并。
class Solution{ public void merge(int nums1 [], int m, int nums2 [], int n){ int i = m-1, j = n-1, k = m+n-1; while(i>=0 && j>=0){ if(nums1[i] > nums2[j]) nums1[k--] = nums1[i--]; else nums1[k--] = nums2[j--]; } while(j>=0){ nums[k--] = nums[j--]; } } }
3.重新排列数组中的正值和负值
4.找到数组中第一个不重复出现的整数
栈
1.使用栈计算后缀表达式
- 从左到右遍历表达式的每个数字和符号,遇到是数字就进栈
- 遇到是符号,就将处于栈顶和次栈顶的两个数字出栈,进行运算
- 运算结果进栈,一直到最终获得结果
2.对栈的元素进行排序
思路:使用一个辅助栈,从原始栈中依次弹出元素放入辅助栈中,每当将要压入的元素使得辅助栈不是升序排列时,就将辅助栈中的元素压入原始栈,直到辅助栈里的元素都小于当前要压入的元素,然后再压入当前元素。
3.判断表达式是否括号平衡
题目:设计一个算法,判断用户输入的表达式中括号是否匹配,表达式中可能含有圆括号、中括号和大括号
思路:建立一个顺序栈,当表达式中有左括号时将其入栈,当出现右括号时,将栈顶元素出栈,检查与当前右括号是否匹配。最后如果栈为空则表示该表达式中的括号是匹配的。
public class Solution { Stack<Integer> stack1 = new Stack<Integer>(); Stack<Integer> stack2 = new Stack<Integer>(); public void push(int node) { stack1.push(node); } public int pop() { if(stack1.isEmpty() && stack2.isEmpty()){ throw new RuntimeException("栈为空"); } if(stack2.isEmpty()){ while(!stack1.isEmpty()){ stack2.push(stack1.pop()); } } return stack2.pop(); } }
队列
1.使用队列表示栈
- push:对于push,我们只需要把所有元素都放进q1中就行
- pop:对于pop,当q1的长度为1的时候,直接pop,当不等于1的时候,我们就要把前n-1个元素放进q2中,然后pop q1的值,再把q1和q2调换
2.对队列的前k个元素倒序
思路:直接把前k个元素压栈,放入新队列中,追加剩余的队列元素
3.使用队列生成从1到n的二进制数
十进制数化二进制数:整数部分用“除二取余“法,将数除以2,将余数放入栈,商再除以2,重复。直至商为0。小数部分用“乘二取整”法,数乘2,然后取整、放入队列里
链表
1.反转链表
方法1:递归
方法2:非递归
2.合并链表
方法1:递归
方法2:非递归