20220504java算法笔试题----------数组

1.如何找出数组中重复唯一的重复的元素

题目描述:

数字1~1000放在含有1001个元素的数组中,其中只有唯一的一个元素值重复,其他数字均只出现一次。设计一个算法,将重复元素找出来,要求每个数组元素只能访问一次。如果不使用辅助存储空间,能否设计一个算法实现? 

import java.util.Hashtable;

/**
 * @author 龙御修
 * @create 2022-05-04 10:04
 */
public class FindRepetitionArrays {
    //在数组中找出唯一重复的元素
    public static int findDup(int[] array){
        if(null==array)
            return -1;
        int len= array.length;
        Hashtable<Integer,Integer> hashtable=new Hashtable<>();
        int i;
        for(i=0;i<len-1;i++)
            hashtable.put(i,0);
            for(i=0;i<len;i++){
                if(hashtable.get(array[i]-1)==0){
                    hashtable.put(array[i]-1,array[i]-1);

                }else {
                    return array[i];
                }
            }
        return -1;
    }

    public static void main(String[] args) {
        int[] array={1,3,4,2,5,3};
        System.out.println(findDup(array));
    }
}

 hashtable:哈希表(HashTable)又叫做散列表,是根据关键码值(即键值对)而直接访问的数据结构。

2.如何查找数组中元素的最大值和最小值

题目描述:

给定数组a1, a2, a3, …, an,要求找出数组中的最大值和最小值。假设数组中的值两两各不相同。

分治法

/**
 * @author 龙御修
 * @create 2022-05-04 17:13
 */
public class MaxMinArrays {
    private int max;
    private int min;

    public int getMax() {
        return max;
    }

    public int getMin() {
        return min;
    }
    public void GetmaxAndmin(int[] arr){
        if(arr==null){
            System.out.println("参数不合法");
            return;
        }
        int i=0;
        int len=arr.length;
        max=arr[0];
        min=arr[0];
        //两两分组,把较小的数放到左半部,较大的放到右半部
        for(i=0;i<len-1;i+=2){
            if(arr[i]>arr[i+1]){
                int tmp=arr[i];
                arr[i]=arr[i+1];
                arr[i+1]=tmp;

            }
        }
        //在各个分组的左半部分找出最小值
        min=arr[0];
        for(i=2;i<len;i+=2) {
            if (arr[i] < min) {
                min = arr[i];

            }
        }
        //在各个分组找出右半部分最大值
        max=arr[1];
        for(i=3;i<len;i+=2) {
            if (arr[i] > max) {
                max = arr[i];
            }
        }

            //如果数组中元素个数是奇数个,最后一个元素被分为一组,需要特殊处理
            if(len%2==1){
                if(max<arr[len-1])
                    max=arr[len-1];
                if(min>arr[len-1])
                    min=arr[len-1];
            }

    }

    public static void main(String[] args) {
        int[] array={7,3,19,40,4,7,1};
        MaxMinArrays m=new MaxMinArrays();
        m.GetmaxAndmin(array);
        System.out.println("max="+m.getMax());
        System.out.println("min="+m.getMin());
    }

}

3.如何找出旋转数组最小元素

题目描述:

把一个有序数组最开始的若干个元素搬到数组的末尾,称之为数组的旋转。输入一个排好序的数组的一个旋转,输出旋转数组的最小元素。例如,数组{3, 4, 5, 1, 2}为数组{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1。

/**
 * @author 龙御修
 * @create 2022-05-04 17:39
 */
public class RpinAarrays {
    public static  int getMin(int[] arr,int low,int high){
        //如果旋转个数为0,即没有旋转,单独处理,直接返回数组头元素
        if(high<low)
            return arr[0];
        //只剩一个元素一定是最小值
        if(high==low)
            return arr[low];
        //mid=(low+high)/2,采用下面写法防止溢出
        int mid=low+((high-low)>>1);
        //判断是否arr[mid]为最小值
        if(arr[mid]<arr[mid-1])
            return arr[mid];
        //判断是否arr[mid+1]为最小值
       else if(arr[mid+1]<arr[mid])
           return arr[mid+1];
       //最小值一定在数组左半部
        else if(arr[high]>arr[mid])
            return getMin(arr,low,mid-1);
       // 最小值一定在数组右半部
        else if(arr[mid]>arr[low])
            return getMin(arr,mid+1,high);
        //arr[low]==arr[mid]&&arr[high]==arr[mid]
        //这种情况下无法确定最小值所在的位置,需要在左右两部分分别进行查找
        else
            return Math.min(getMin(arr,low,mid-1),getMin(arr,mid+1,high));
    }
    public static int getMin(int[] arr){
        if(arr==null){
            System.out.println("参数不合法");
            return -1;

        }else
            return getMin(arr,0, arr.length-1);

    }

    public static void main(String[] args) {
        int[] array1={5,6,1,2,3,4};
        int min=getMin(array1);
        System.out.println(min);
        int[]array2={1,1,0,1};
        min=getMin(array2);
        System.out.println(min);
    }
}

4. 如何实现旋转数组功能? 

package array;

public class RpinArray {
    public static void swap(int[] arr,int low,int high){
        //交换数组low到high的内容
        for(;low<high;low++,high--){
            int tmp=arr[low];
            arr[low]=arr[high];
            arr[high]=tmp;
        }
    }
    public static void rotatearr(int[] arr,int div){
        if(arr==null||div<0||div>= arr.length){
            System.out.println("参数不合法");
            return;
        }
        //不需要旋转
        if(div==0||div== arr.length-1)
            return;
        //交换第一个子数组的内容
        swap(arr,0,div);
        //交换第二个数组内容
        swap(arr,div+1, arr.length-1);
        //交换整个数组的元素
        swap(arr,0, arr.length-1);
    }

    public static void main(String[] args) {
        int[] arr={1,2,3,4,5};
        rotatearr(arr,2);
        for (int i=0;i< arr.length;i++)
            System.out.print(arr[i]+" ");

    }


}

 5.如果找出数组中丢失的数

题目描述:

给定一个由n-1个整数组成的未排序的数组序列,其元素都是1到n中的不同的整数。请写出一个寻找数组序列中缺失整数的线性时间算法。

package array;

public class DropArray {
    //累加法
    public static int getnum(int[] arr){
        if(arr==null||arr.length<=0){
            System.out.println("参数不合法");
            return -1;
        }
        int suma=0,sumb=0;
        int i;
        for(i=0;i<arr.length;i++){
            suma=suma+arr[i];
            sumb=sumb+i;
        }
        sumb=sumb+arr.length+arr.length+1;
        return sumb-suma;
    }
    //异减法
    public static int getnum1(int[]arr){
        if(arr==null||arr.length<=0){
            System.out.println("参数不合法");
            return -1;
        }
        int a=arr[0],b=1;
        int i;
        int len=arr.length;
        for(i=1;i<len;i++){
            a=a^arr[i];
        }
        for(i=2;i<=len+1;i++){
            b=b^i;
        }
        return a^b;
    }

    public static void main(String[] args) {
        int[] arr={1,4,3,2,7,5};
        System.out.println(getnum(arr));
        System.out.println(getnum1(arr));
    }
}

6.如何找出数组中出现奇数次的数

题目描述:

数组中有N+2个数,其中,N个数出现了偶数次,两个数出现了奇数次(这两个数不相等),请用O(1)的空间复杂度,找出这两个数。注意:不需要知道具体位置,只需要找出这两个数。

package array;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class UnevenArray {
    public static void get2Num(int[] arr){
        if(arr==null||arr.length<1){
            System.out.println("参数不合理");
            return;
        }
        HashMap<Integer,Integer> map=new HashMap<>();
        int i;
        for(i=0;i<arr.length;i++){//map中没有整个数字,说明第一次出现,value赋值为1
            if(!map.containsKey(arr[i])){
                map.put(arr[i],1 );
                //当前遍历的值在map中存在,说明前面出现过,value赋值为0
            }else {
                map.put(arr[i],0 );
            }
        }
       Iterator<Map.Entry<Integer,Integer>>iter=map.entrySet().iterator();
        while (iter.hasNext()){
            Map.Entry<Integer,Integer>entry=(Map.Entry<Integer, Integer>) iter.next();
            if(entry.getValue()==1)
                System.out.println(entry.getKey());
        }
    }
  //异或法
    public static void get1Num(int[] arr) {
        if(arr==null||arr.length<1){
            System.out.println("参数不合理");
            return;
        }
        int result=0;
        int position=0;
        //计算数组中所有数字异或的结果
        for(int i=0;i< arr.length;i++){
            result=result^arr[i];
        }
        int tmpResult=result;//临时保存异或结果
        //找出异或结果中其中一个位置为1的位数(如1100,位置为1位数为2和3)
       for (int i=result;(i&1)==0;i=i>>1){
           position++;
       }
       for(int i=0;i< arr.length;i++){
           //异或的结果与所有第position位为1的数异或,结果一定是出现两个数其中一个
           if(((arr[i]>>position)&1)==1){
               result=result^arr[i];
           }
       }
        System.out.println(result);
       //得到另一个出现一次的数
        System.out.println(result^tmpResult);

    }


    public static void main(String[] args) {
        int[] arr={3,5,6,6,5,7,2,2};
        get2Num(arr);
    }
}

7.如何找出数组中第K小的数 

题目描述:

给定一个整数数组,如何快速地求出该数组中第k小的数。假如数组为{4,0,1,0,2,3},那么第三小的元素是1。部分排序法

package queue;
//类快速排序方法
public class Findsoft {
   //在数组array中找到第k小的值
    public static  int findSmallk(int[] array ,int low,int high,int k){
        int i,j;
        int splitElem;
        i=low;
        j=high;
        splitElem=array[i];
        //把小于等于splitElem的数放到数组中splitElem的左边,大于spliElem的值放到右边
        while (i<j){
            while (i<j&&array[i]>=splitElem)
                j--;
            if(i<j)
                array[i++]=array[j];
            while (i<j&&array[i]<=splitElem)
                i++;
            if(i<j)
                array[j--]=array[i];
        }
        array[i]=splitElem;
//        splitElem 在子数组array[low~high]中下标的偏移量
        int subArrayIndex=i-low;
//    splitElem 在array[low~high]所在的位置恰好为k-1,那么它就是第k小的元素
        if(subArrayIndex==k-1)
            return array[i];
        else if(subArrayIndex>k-1)
            return findSmallk(array, low, i-1, k);
//        在array[i+1~high]中找第k-i+low-1小的元素
        else
            return findSmallk(array,i+1, high, k-(i-low)-1);
    }

    public static void main(String[] args) {
        int k=3;
        int[] array={4,0,1,2,3};
        System.out.println("第"+k+"小的值为:"+findSmallk(array,0,array.length-1,k));

    }
}

8.如何求数组中两个元素的最小距离

题目描述:

给定一个数组,数组中含有重复元素,给定两个数字num1和num2,求这两个数字在数组中出现的位置的最小距离。

package array;

public class FindArray {
    //动态规划
    public static int minDistance(int [] arr,int num1,int num2){
        if(arr==null||arr.length<=0){
            System.out.println("参数不合理");
            return Integer.MAX_VALUE;
        }
        int lastPos1=-1; //上次遍历到num1的位置
        int lastPos2=-1;//上次遍历到num2的位置
        int minDis=Integer.MAX_VALUE;//num1与num2的最小距离
        for(int i=0;i< arr.length;i++){
            if(arr[i]==num1){
                lastPos1=i;
                if(lastPos2>=0)
                    minDis=Math.min(minDis,lastPos1-lastPos2);
            }
            if(arr[i]==num2){
                lastPos2=i;
                if(lastPos1>=0)
                    minDis=Math.min(minDis,lastPos2-lastPos1);
            }

        }
        return minDis;
    }

    public static void main(String[] args) {
        int[]arr={4,5,6,7,4,6,4,7,8,5,6,4,3,10,8};
        int num1=4;
        int num2=8;
        System.out.println(minDistance(arr,num1,num2));
    }
}

9.如何求解最小三元 组距离

题目描述:

已知三个升序整数数组a[l]、b[m]和c[n],在三个数组中各找一个元素,使得组成的三元组距离最小。三元组距离的定义:假设a[i]、b[j]和c[k]是一个三元组,那么距离为:Distance=max(|a[i]-b[j]|,|a[i]-c[k]|,|b[j]-c[k]|),设计一个求最小三元组距离的最优算法。

public class Distancearray {
    //最小距离法
    public static int min(int a,int b ,int c){
        int min=a<b?a:b;
        min=min<c?min:c;
        return min;
    }
    public static int max(int a,int b ,int c){
        int max=a<b?b:a;
        max=max<c?c:max;
        return max;
    }
    public static int minDistance(int[] a,int[] b,int[] c){
        int aLen=a.length;
        int bLen=b.length;
        int cLen=c.length;
        int curDist=0;
        int min=0;
        int minDist=Integer.MAX_VALUE;
        int i=0;//数组a的下标
        int j=0;//数组b的下标
        int k=0;//数组c的下标
        while (true){
//            Math.abs 返回绝对值
            curDist=max(Math.abs(a[i]-b[j]),Math.abs(a[i]-c[k]),Math.abs(b[j]-c[k]));
           if(curDist<minDist)
               minDist=curDist;
           //找出当前遍历到三个数组中的最小值
            min=min(a[i],b[j],c[k]);
            if(min==a[i]){
                if(++i>=aLen)
                    break;
            }else if(min==b[j]){
                if(++j>=bLen)
                    break;
            }else {
                if(++k>=cLen)
                    break;
            }
        }
        return minDist;
    }

    public static void main(String[] args) {
        int[] a={3,4,5,7,15};
        int[] b={10,12,14,16,17};
        int[] c={20,21,23,24,37,30};
        System.out.println("最小距离为:"+minDistance(a,b,c));
    }
}

10.如何求数组中绝对值最小的数 

 题目描述:

有一个升序排列的数组,数组中可能有正数、负数或 0,求数组中元素的绝对值最小的数。例如,数组{-10,-5,-2, 7, 15, 50},该数组中绝对值最小的数是-2。

package array;

public class SabArray {
    public static int findMin(int[] array){
        if(array==null||array.length<=0){
            System.out.println("输入参数");
            return 0;
        }
        int len= array.length;
        //数组中没有负数
        if(array[0]>=0)
            return array[0];
        //数组中没有正数
        if(array[len-1]<=0)
            return array[len-1];
        int mid=0;
        int begin=0;
        int end=len-1;
        int absMin=0;
        //数组中既有正数又有负数
        while (true){
            mid=begin+(end-begin)/2;
            //如果等于0那么绝对值最小的数
            if(array[mid]==0){
                return 0;
                //如果大于0,正负数的分界线在左侧
            }else if(array[mid]>0){
                //继续在数组的左半部查找
                if(array[mid-1]>0)
                    end=mid-1;
                else if(array[mid-1]==0)
                    return 0;
                //找出正负数的分界线
                else
                    break;
            }else{//如果小于0,在数组右半部分查找
                if(array[mid+1]<0)
                    begin=mid+1;
                else if(array[mid+1]==0)
                    return 0;
                //找出正负数分界线
                else
                    break;
            }

        }
        //获取正负数分界点出绝对值最小的值
        if(array[mid]>0){
            if(array[mid]<Math.abs(array[mid-1]))
                absMin=array[mid];
            else
                absMin=array[mid-1];
        }else {
            if(Math.abs(array[mid])<array[mid+1])
                absMin=array[mid];
            else
                absMin=array[mid+1];
        }
        return absMin;
    }

    public static void main(String[] args) {
        int arr[] ={-10,-5,-2,7,15,50};
        System.out.println("绝对值最小的数为"+findMin(arr));
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java算法笔试题及答案有很多种,以下是一个简单的例子: 题目:给定一个整数数组nums和一个目标值target,在数组中找出和为目标值的两个整数,并返回它们的索引。 解法: ```java public int[] twoSum(int[] nums, int target) { HashMap<Integer, Integer> map = new HashMap<>(); for (int i = 0; i < nums.length; i++) { int complement = target - nums[i]; if (map.containsKey(complement)) { return new int[] {map.get(complement), i}; } map.put(nums[i], i); } throw new IllegalArgumentException("No two sum solution"); } ``` 解析: 该算法使用了哈希表来记录数组元素的值和索引。首先创建一个HashMap对象,然后遍历数组nums。在遍历过程中,计算目标值与当前元素的差值,并检查差值是否已经在哈希表中存在。如果存在,说明找到了符合条件的两个数,返回它们的索引;如果不存在,则将当前元素及其索引放入哈希表中以备后续使用。最后,如果没有找到符合条件的两个数,抛出一个IllegalArgumentException异常。 这个算法的时间复杂度是O(n),其中n是数组nums的长度。因为每个元素最多只遍历一次,而哈希表的访问时间是常数级别的。空间复杂度也是O(n),因为需要额外的哈希表存储元素的值和索引。 这只是一个简单的例子,实际的算法笔试题及答案可能更加复杂。不同的算法问题有不同的解法,可以根据具体的问题和要求灵活选择适合的算法

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Royalreairman

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值