程序设计入门

估算程序运行时间

编写了一个程序,根据题目给出的条件限制,来估算自己的代码能不能通过测试。
当考虑一个O(n^2)时间的算法,假设题目描述中的限制条件为 n <= 1000,
将n=1000带入n^2就等于1000000。根据下表就能初略的判断代码会不会运行超时了。
在这里插入图片描述

L001

在这里插入图片描述在这里插入图片描述

从n根棍子中挑选3根,在所有满足其中两边之和大于第三边的三角形中,选取周长最大的三角形。

方法一:枚举法(不断尝试每三根棍子可不可以组成三角形,并与最大周长进行比较)

public static int[] generateRandomArray(int maxSize, int maxValue) {
		int[] arr = new int[(int) ((maxSize + 1) * Math.random())];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = (int) (maxValue * Math.random()+1);
		}
		return arr;
	}

public static void main(String[] args) {		
		int testTime = 1;
		int maxSize = 1000;
		int maxValue = 1000000;
		boolean succeed = true;
		for (int i = 0; i < testTime; i++) {
			int[] arr1 = generateRandomArray(maxSize, maxValue);
			
			long start = System.currentTimeMillis();
			int r1 = solve1(arr1);
			long end = System.currentTimeMillis();
			System.out.println("cost time: " + (end - start) + "ms");
			
			start = System.currentTimeMillis();
			int r2 = solve2(arr1);
			end = System.currentTimeMillis();
			System.out.println("cost time: " + (end - start) + "ms");
			
			if (r1 != r2) {
				succeed = false;
				break;
			}
		}
		System.out.println(succeed ? "Nice!" : "Fucking fucked!");
	}

在这里插入图片描述
修改testTime的值可以多次执行,避免特殊性的数据导致两个方法结果相同,但实际上两个方法可能是有一定问题的。

L002

在这里插入图片描述在这里插入图片描述
首先最短时间,在中点左边的蚂蚁朝左爬,在中点右边的蚂蚁朝右边爬即可,也不会出现相遇问题。
当考虑最长时间时,就需要考虑相遇问题了,看似很复杂,实则很简单。
在这里插入图片描述
当相遇时只需认为蚂蚁依旧朝原来方向走即可。

public static int[] solve(int l,int[] arr) {
		int[] result = new int[2];
		for (int i = 0; i < arr.length; i++) {
			int min = arr[i] < l - arr[i] ? arr[i] : l - arr[i];
			result[0] = Math.max(min, result[0]); 
		}
		for (int i = 0; i < arr.length; i++) {
			int max = arr[i] > l - arr[i] ? arr[i] : l - arr[i];
			result[1] = Math.max(max, result[1]); 
		}
		return result;
	}

L003

在这里插入图片描述
在这里插入图片描述
方法一:暴力枚举,O(n ^ 4)的时间复杂度

public static boolean solve1(int[] arr,int k) {
		for (int a = 0; a < arr.length; a++) {
			for (int b = 0; b < arr.length; b++) {
				for (int c = 0; c < arr.length; c++) {
					for (int d = 0; d < arr.length; d++) {
						if (arr[a] + arr[b] + arr[c] + arr[d] == k) {
							return true;
						}
					}
				}
			}
		}
		return false;
	}

方法二:利用二分搜索,将O(n ^ 4)的时间复杂度变为O(n ^ 3 * log n)

public static boolean binary_search(int[] arr,int x) {
		int left = 0;
		int right = arr.length - 1;
		while (left <= right) {
			int mid = left + (right - left) / 2;
			if (arr[mid] == x) {
				return true;
			}
			if (arr[mid] > x) {
				right = mid - 1;
			}
			if (arr[mid] < x) {
				left = mid + 1;
			}
		}
		return false;
	}
	
	public static boolean solve2(int[] arr,int k) {
		Arrays.sort(arr);
		for (int a = 0; a < arr.length; a++) {
			for (int b = 0; b < arr.length; b++) {
				for (int c = 0; c < arr.length; c++) {
					if (binary_search(arr, k - arr[a] - arr[b] - arr[c])) {
						return true;
					}
				}
			}
		}
		return false;
	}

方法三:方法二的二分搜索,搜索的是一个数,而现在的方法三则搜索的是两个数加起来的值
时间复杂度变为O(n ^ 2 * log n)

public static boolean solve3(int[] arr,int k) {
		int[] arr1 = new int[arr.length * arr.length];
		for (int c = 0; c < arr.length; c++) {
			for (int d = 0; d < arr.length; d++) {
				arr1[c*arr.length + d] = arr[c] + arr[d];
			}
		}
		Arrays.sort(arr1);
		for (int a = 0; a < arr.length; a++) {
			for (int b = 0; b < arr.length; b++) {
				if (binary_search(arr1, k - arr[a] - arr[b])) {
					return true;
				}
			}
		}
		return false;
	}

测试:

public static int[] randomArray(int maxSize,int maxValue) {
		int[] arr = new int[(int)(Math.random()*maxSize + 1)];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = (int)(Math.random() * maxValue + 1);
		}
		return arr;
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int testTime = 50;
		int maxSize = 500;
		int maxValue = 100000000;
		for (int i = 0; i < testTime; i++) {
			int[] arr = randomArray(maxSize, maxValue);
			int k = (int)(Math.random() * maxValue + 1);
			long start = System.currentTimeMillis();
			solve1(arr, k);
			long end = System.currentTimeMillis();
			System.out.println("cost: " + (end - start) + "ms");
			
			start = System.currentTimeMillis();
			solve2(arr, k);
			end = System.currentTimeMillis();
			System.out.println("cost: " + (end - start) + "ms");
			
			start = System.currentTimeMillis();
			solve3(arr, k);
			end = System.currentTimeMillis();
			System.out.println("cost: " + (end - start) + "ms");
			
		}
		
	}

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值