标签:
循环不变式:如果某命题初始为真,且每次更改后仍然保持该命题为真,则若干次更改后该命题仍然为真。
1. 求局部最大值
问题描述:给定一个无重复元素的数组A[0...N-1],求找到一个该数组的局部最大值。
分析思路:
/** * Get the local maximum from an array * @param nums * @return */ public int getLocalMax(int[] nums) { int left=0; int right = nums.length-1; int mid = 0; while(left < right) { mid = (left + right) / 2; if(nums[mid] > nums[mid+1]) right = mid; else if(nums[mid] < nums[mid+1]) left = mid+1; } return nums[left]; }
2. 第一个缺失的整数
问题描述:给定一个数组A[0...N-1],找到从1开始,第一个不在数组中的正整数。
如:3,5,1,2,-3,7,14,8输出4.
分析思路:
/** * Find the fist positive integer not presented in the array count from 1. * @param nums * @return */ public int getMinPosNotExist(int[] nums) { int i = 0; int len = nums.length; while(i < len) { if(nums[i] == i+1) i++; else if(nums[i] <= 0 || nums[i] >= len || nums[i] < i-1 ) { nums[i] = nums[len-1]; len--; } else if(nums[i] > i+1 ) { int temp = nums[i]; nums[i] = nums[nums[i]-1]; nums[temp-1] = temp; } } return i+1; }
3. 查找旋转数组的最小值
问题描述:假定一个排序数组一某个未知元素为支点做了旋转,如原数组0,1,2,3,4,5,6,7旋转后得到了4,5,6,7,0,1,2。找出旋转后的数组的最小值。假定数组中没有重复数字。
分析思路:
/** * Get the minimum element of a rotate array. * @param nums * @return */ public int getMiniOfRotateArray(int[] nums) { int left = 0; int right = nums.length-1; int mid; while(left < right) { mid = (left + right) / 2; if(nums[mid] > nums[right]) left = mid+1; else if(nums[mid] < nums[right]) right = mid; } return nums[left]; }
4. 求一个子数组的值最接近0的问题。
问题描述:求对于长度为N的数组A,求连续子数组的和最接近0的值。如数组A:1,-2,3,10,-4,7,2,-5.它的所有子数组中,和最接近0的是[-4,7,2,-5],和为0.
分析思路:这种求子数组和的问题,一般需要有一个辅助数组,存储中间计算的过程。
用一个sum数组,第i个元素表示:该数组中从第1个元素到第i-1个元素的和,则从i到j这一段子数组的和为:sum[j]-sum[i-1]。
因为我们的数组中保存了每段子数组的和,则在所有子数组的和中差别最少的那部分就是要求的子数组的和。
也就是我们可以将所求的sun数组进行排序,然后返回相邻元素的差的绝对值最小的那个。
/** * Get the minimum sum of continues subArray which is closest to 0. * @param nums * @return */ public int getClosestToZero(int[] nums) { int[] sum = new int[nums.length]; sum[0] = nums[0]; for(int i=1; i<nums.length; i++) { sum[i] = sum[i-1] + nums[i]; } Arrays.sort(sum); int res = Integer.MAX_VALUE; int temp = 0; for(int i=1; i<sum.length; i++) { temp = Math.abs(sum[i] - sum[i-1]); res = Math.min(temp, res); } return res; }
5. 最大子数组的和。
问题描述:给定一个数组A[0,...,n-1],求A的连续子数组,是的该子数组的和最大。
例如:数组:1,-2,3,10,-4,7,2,-5,最大子数组为:3,10,-4,7,2
思路分析:
这个题目与上面的题目不同,可以使用DP的思想来解决了。
/** * Get the max sum of subArray. * @param nums * @return */ public int getMaxSumOfSubArray(int[] nums) { int[] sum = new int[nums.length]; sum[0] = nums[0]; int res = sum[0]; for(int i=1; i<nums.length; i++) { sum[i] = Math.max(sum[i-1]+nums[i], nums[i]); res = Math.max(res, sum[i]); } return res; }
标签:
原文地址:http://www.cnblogs.com/little-YTMM/p/5456780.html