数据结构-数组

O(1)时间读写任何元素,时间效率高

用数组实现简单的哈希表

把数组的下标设为哈希表的键值(Key)

把数组中的没一个数组设为哈希表的值(Value)

这样每一个下表及数组中改下表对应的数字就组成了一个键值对,就可以在O(1)时间内实现查找

在C++中,当数组作为函数的参数进行传递时,数组会自动退化为同类型的指针

 

面试题3.数组中的重复数字

题干:

在一个长度为n的数组里的所有数字都在0~n-1的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中重复的数字

 

方法一:排序

先把输入的数组排序,从排序的数组中找出重复的数字,O(nlogn)

public class arrayRepeatNumber {
    public static void main(String[] args){
        int[] num={2,3,1,0,2,5,3};
//        int[] num={1,1,2,2,2,2,3,3,4};
        quickSort(num,0, num.length-1);
        locate(num);
    }
    public static void quickSort(int[] num,int left,int right){
        if(left<right){
            int i=left,j=right,x=num[left];
            while(i<j){
                while(i<j&&num[j]>=x){
                    j--;
                }
                if(i<j){
                    num[i++]=num[j];
                }
                while(i<j&&num[i]<x){
                    i++;
                }
                if(i<j){
                    num[j--]=num[i];
                }
            }
            num[i]=x;
            quickSort(num,left,i-1);
            quickSort(num,i+1,right);
        }
    }
    public static void locate(int[] num){
        int len= num.length;
        int point=0;
        int mark=1;
        while(point<len-1){
            if(num[point]==num[point+mark]){
                mark++;
            }
            else{
                point=point+mark;
                mark=1;
            }
            if(mark==2){
                System.out.println(num[point]);
            }
        }
    }
}

 

方法二:哈希表

从头到尾按顺序扫描数组的每个数字,没扫描到一个数字的时候都可以用O(1)的时间判断哈希白哦里是否已经包含了该数字。如果哈希表里没有这个数字,就把它加入哈希表。如果哈希表里已经存在该数字,就找到一个重复的数字。算法时间复杂度O(n),但需要一个O(n)的哈希表为代价

public static void findRepeatNumber(int[] num) {
    //定义一个集合hashset
    Set<Integer> set = new HashSet<Integer>();
    //定义重复的标记
    int repeat = -1;
    //对数组进行遍历
    for (int i=0;i<num.length;i++) {
        repeat=-1;
        //如果添加失败(set不能添加重复元素),说明有重复元素
        if (!set.add(num[i])) {
            //重复标记=当前数字
            repeat = num[i];
        }
        if(repeat!=-1){
            System.out.println(repeat);
        }
    }
}

 

方法三:下标映射

空间复杂度O(1)

如果只需要找到其中一个重复数字,则可以用下标法

//数组下标法
public static int subscript(int[] num){
    for(int i=0;i< num.length;i++){
        while(num[i]!=i){
            if(num[i]==num[num[i]]){
                return num[i];
            }
            int tmp=num[num[i]];
            num[num[i]]=num[i];
            num[i]=tmp;
        }
    }
    return -1;
}

 

面试题4.二维数组中的查找

题干:在一个二维数组中,每一行都按照从左到右递增的顺序排列,每一列都按照从上到下递增的顺序排列。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数

1 2  8   9

2 4  9  12

4 7 10 13

6 8 11 15

 

方法:找规律,观察矩阵,往右和往下数字都在增大。可以从右上方或者左下方开始找。

①如果从右上方元素开始找,如果目标数字大于当前元素,则行坐标往左移。如果目标数字小于当前元素,则列坐标往下移。

②如果从左下方元素开始找,如果目标数字大于当前元素,则列坐标往右移。如果目标数字小于当前元素,则行坐标往上移。

本代码选取第一种方法

public class matrixSearch {
    public static boolean matrixSearch(int[][] matrix ,int rows, int columns,int number){
        boolean found=false;
        if(matrix!=null&&matrix.length>=0&&rows>0&&columns>0){
            int row=0;
            int column=columns-1;
            while(row<rows&&column>=0){
                if(matrix[row][column]==number){
                    found=true;
                    break;
                }
                else if(matrix[row][column]>number){//如果当前元素比目标大
                    column--;//左移寻找
                }
                else{//如果当前元素比目标小
                    row++;//下移寻找
                }
            }
        }
        return found;
    }
    public static void main(String[] args){
        int[][] num={{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}};
        System.out.println(matrixSearch(num,4,4,7));
    }
}

 

posted @ 2021-02-20 10:47  Heinrich♣  阅读(30)  评论(0编辑  收藏  举报