【迅雷】 2019校招在线考试两道编程题

版权声明:本文为博主原创文章,欢迎大家转载,但是要注明我的文章地址。 https://blog.csdn.net/program_developer/article/details/82668661

1. 给你一个无序数组,找出数组中的一个数,使得在数组中,这个数之前的所有数字之和等于这个数之后所有数字之和。

输入:

输入一行数字,每个数字用逗号隔开。

 输出:

存在这个数,则输出这个数。不存在这个数,则输出False。

样例:

输入:

1,3,4,4

输出

4

解题思路:

(1)遍历数组法

看到这题,第一个想法就是从头到尾遍历数组,然后计算左边之和,右边之和,比较它们。

代码:

	public static int stuFind(int[] array){
		for(int i=1;i<array.length;i++){
			int totalLeft=0;
			for(int le=0;le<i;le++){
				totalLeft+=array[le];
			}
			int totalRight=0;
			for(int ri=i+1;ri<array.length;ri++){
				totalRight+=array[ri];
			}
			if(totalLeft==totalRight){
				return i;
			}
		}
		return -1;
	}

(2)对遍历数组的优化法

遍历法时间复杂度应该是O(n^{2})。其实还可以优化一下,反正是顺序后移,计算可以偷懒一下,当你第一次计算左边的值和右边的值以后,第二次移动,左边的值等于原先左边的值+当前位置前一个位置的值,右边的值等于原先右边的值减去当前的位置的数字的值。

代码:

	public static int stuFind(int[] array){
		int totalLeft=0;
		int totalRight=0;
		for(int i=1;i<array.length;i++){
			if(i==1){
				for(int le=0;le<i;le++){
					totalLeft+=array[le];
				}
				for(int ri=i+1;ri<array.length;ri++){
					totalRight+=array[ri];
				}
			}else{
				totalLeft+=array[i-1];
				totalRight-=array[i];
			}
		
			if(totalLeft==totalRight){
				return i;
			}
		}
		return -1;
	}

(3)二分查找法

既然某个数字的左边的值等于右边,那么可以算出数组的全部数值,然后加入一个二分查找的办法,定位到中间,如果左边的值*2=数组的和-当前位置的值,那么就可以说找到了,如果大于,那就向前移动,小于就向后移动。

思考:为什么要左边的值*2,而不是(数组的和-当前位置的值)/2 ?

我的想法是:(数组的和 - 当前位置的值)/ 2 的值可能为float类型。在Java中会对这个值自动的向下取整,变成int类型。那么在进行(数组的和 - 当前位置的值)/ 2 = 左边值的和 比较的时候,就会出现精度的偏差。

最优代码:

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		String str = sc.next();
		String[] strArray = str.split(",");
		int[] array = new int[strArray.length];
		for(int i=0; i<strArray.length; i++) {
			array[i] = Integer.parseInt(strArray[i]);
		}
		int index = splitFindNum(array);
		if(index == -1) {
			System.out.println("False");
		}else {
			System.out.println(array[index]);
		}
		
	}
	
	public static int splitFindNum(int[] array) {
		if (null == array || array.length == 0) {
			return -1;
		}
		int length = array.length;
		int low, high, index;
		low = 0;
		high = length - 1;
		index = length / 2;
		int sum = 0;
		for (int i : array) {
			sum += i;
		}
		do {
			int totalLow = 0;
			for (int le = 0; le < index; le++) {
				totalLow += array[le];
			}
			int doub2Val=(sum - array[index]);
			if (totalLow*2 < doub2Val) {
				low=index;
				index = index + (length - index) / 2;
			} else if (totalLow*2 > doub2Val) {
				high=index;
				index = low + (index - low) / 2;
			} else {
				return index;
			}
		} while (index > low && index < high);
		return -1;
	}

}

Reference:

算法:请找出数组中的某个数,它的左侧数字相加之和等于右边。 

2.给你两个无序数组M、N,输出两个数组中和最大的前K个数。在求和时,一个数来自M、另一个数来自N。

 输入:输入一行,数组间用横杠(-)隔开,数组内数字用逗号隔开,最后用冒号隔开K。

 输出:输出一行,输出前K大的数,每个数字用逗号隔开。

样例:

输入:

2,4,2,7,7-3,2,5,6,1,9:6

输出:

16,16,13,13,13,12 

解题思路:

(1)排序法

首先对M、N进行快速排序,然后求出数组中任意两个数字的和,再对所有的和进行排序,选出前K大的数字。这样写首先时间复杂度太高,不知道能不能AC,其次这个算法肯定是不行的,感觉是拿不到offer的。

代码:

import java.util.Scanner;

public class Main2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		String str = sc.next();
		String[] twoStr = str.split(":");
		int k = Integer.parseInt(twoStr[1]);
		String[] twoArray = twoStr[0].split("-");
		String[] m2Str = twoArray[0].split(","); 
		int[] M = new int[m2Str.length];
		String[] n2Str = twoArray[1].split(",");
		int[] N = new int[n2Str.length];
		for(int i=0; i<m2Str.length;i++) {
			M[i] = Integer.parseInt(m2Str[i]);
		}
		for(int j= 0; j<n2Str.length;j++) {
			N[j] = Integer.parseInt(n2Str[j]);
		}
		quickSort(M,0,M.length-1);
		quickSort(N, 0, N.length-1);
		int[] sum = new  int[M.length * N.length];
		int l=0;
		for(int i=0; i< M.length; i++) {
			for(int j=0; j<N.length; j++) {
				sum[l] = M[i] + N[j];
				l++;
			}
		}
		quickSort(sum, 0, sum.length-1);
		int temp = sum.length;
		String output = "";
		while(temp > sum.length - k) {
			temp--;
			output += sum[temp] + ",";
		}
		System.out.println(output.substring(0,output.length()-1));
	}
	
	public static void quickSort(int[] arr, int start, int end) {
		  if (start < end) {
		   int key = arr[start];
		   int right = start;
		   int left = end;
		   while (right < left) {
		    while (right < left && arr[left] > key) {
		     left --;
		    }
		    if (right < left) {
		     arr[right] = arr[left];
		    }
		    while (right < left && arr[right] <= key) {
		     right ++;
		    }
		    if (right < left) {
		     arr[left] = arr[right];
		    }
		   }
		   arr[right] = key;
		   quickSort(arr, start, right-1);
		   quickSort(arr, left+1, end);
		  }
		 }

}

猜你喜欢

转载自blog.csdn.net/program_developer/article/details/82668661