2017尼毕鲁笔试算法题

【1】题目: 给定一个无序数组,找到最长的单调自增子序列(不一定连续,但是顺序不能乱)的长度;

【2】看个荔枝:给定数组  [10, 9, 2, 5, 3, 7, 101, 18]   输出结果为 [2, 3, 7, 101]。。算法时间复杂度一般为 O(n^2) 也可以优化到 O(nlgn);

【3】算法思路:对无序数组做一次遍历 并找出最小最大值v1, v2及其下标i1, i2;下一次循环遍历的范围是在 [i1+1, i2-1] 这个范围内找出 最小最大值 及其下标,每次循环 counter += 2...... 算法结束标志是 i1 小于i2;且当 i1等于i2时 表明 单调自增子序列的长度是奇数,所以counter++;算法实现如下:下面算法的时间复杂度是 O(n^2);

// input: [10, 9, 2, 5, 3, 7, 101, 18]
// output: [2, 3, 7, 101]

public class NiBiNuCycle {
	static int counter = 0;
	
	public static void main(String[] args) {
//		int[] array = {10, 9, 2, 5, 3, 7, 101, 18};
		int[] array = {10, 90, 76, 12, 25, 36, 78, 99, 177, 132, 156};
		find(array, 0, array.length-1);
		System.out.println("result = " + counter);
	}
	
	static void find(int[] array, int i1, int i2) {
		int ci1=0, ci2=0; 
		// ci1, ci2 是 i1 和 i2 的 copy
		// v1 v2 作为在范围 [i1, i2] 区域中的最小最大值.
		// 
		while(i1<i2) {
			int v1 = Integer.MAX_VALUE, v2 = Integer.MIN_VALUE;
			ci1=i1; ci2=i2;
			for (int i = i1; i <= i2; i++) {
				if(array[i] > v2) {
					v2 = array[i];
					ci2 = i;
				} 
				if(array[i] < v1) {
					v1 = array[i];
					ci1 = i;
				}
			}
			System.out.println("v1 = " + v1 + ", v2 = " + v2);
			i1 = ci1+1;
			i2 = ci2-1;			
			counter += 2;
		}
		if(i1==i2) {
			counter++;
		}				
	}
}
【4】O(nlgn)的时间复杂度的思路是:利用分治思想,下面给出伪代码,但源码未实现,仅供参考;

// input: [10, 9, 2, 5, 3, 7, 101, 18]
// output: [2, 3, 7, 101]

// 此题的分治版本.(伪代码,源码未实现)
class MinMax {
	int i1; // 最小值的对应index
	int i2; // 最大值的......
	public MinMax(int i1, int i2) {
		this.i1 = i1;
		this.i2 = i2;
	}
	public MinMax(){}
}
public class NiBiNuRecursion {
	static int counter = 0;
	static MinMax result;
	
	public static void main(String[] args) {
		int[] array = {10, 90, 76, 12, 25, 78, 99, 177, 132, 156};
		find(array, 0, array.length-1);
		System.out.println("result = " + counter);
	}
	// 分治算法.
	static MinMax find(int[] array, int i1, int i2) {
		if(i1<i2) {
			int center = (i1+i2)/2;
			MinMax a = find(array, i1, center);
			MinMax b = find(array, center+1, i2);
			merge(...); // 这里应该要做一次merge.
		} 
		else 
			return new MinMax(i1,i1);
		return result;
	} 
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值