数据结构面试题

数组

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.判断表达式是否括号平衡

题目:设计一个算法,判断用户输入的表达式中括号是否匹配,表达式中可能含有圆括号、中括号和大括号

思路:建立一个顺序栈,当表达式中有左括号时将其入栈,当出现右括号时,将栈顶元素出栈,检查与当前右括号是否匹配。最后如果栈为空则表示该表达式中的括号是匹配的。

4.用两个栈实现队列

 

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:非递归

 

 

 

posted @ 2019-11-24 14:46  落地成霜  阅读(441)  评论(0编辑  收藏  举报