[Algorithm]九章六之二: Array
来源:互联网 发布:c语言遗传算法原理 编辑:程序博客网 时间:2024/06/05 01:12
6. Merge Two Sorted Arrays :点击打开链接
class Solution { /** * @param A and B: sorted integer array A and B. * @return: A new sorted integer array */ public int[] mergeSortedArray(int[] A, int[] B) { if(A==null || B==null){ return null; } int[] result=new int[A.length+B.length]; int i=0,j=0,index=0; while(i<A.length && j<B.length){ //两个数组都从头元素一次比较,哪个的当前元素大,result数组里就装哪个 if(A[i]<B[j]){ result[index++]=A[i++]; //result数组的索引和两数组之一的索引同步推进 }else{ result[index++]=B[j++]; } } while(i<A.length){ //当一个数组全部比较完,只剩下另一个数组的一些元素,也要全部转入result result[index++]=A[i++];; } while(j<B.length){ result[index++]=B[j++]; } return result; }}
64. Merge Sorted Array:点击打开链接
因为添加或减少一个元素数组整体平移:O(n)
因此添加或减少m个元素而平移:O(m*n),与题O(m+n)不符,因此不能用整体平移
class Solution { /** * @param A: sorted integer array A which has m elements, * but size of A is m+n * @param B: sorted integer array B which has n elements * @return: void */ public void mergeSortedArray(int[] A, int m, int[] B, int n) { //这题要先理解题意,A有足够空间装所有A和B的元素 int i=m-1,j=n-1,lastIndex=m+n-1; //而且要merge B into A while(i>=0 && j>=0){ //从后面开始,先放大的,倒着来 if(A[i]>B[j]){ //因为A和Bsorted array,所以不会存在没有地方放的情况 A[lastIndex--]=A[i--]; }else{ A[lastIndex--]=B[j--]; } } while(i>=0){ A[lastIndex--]=A[i--]; } while(j>=0){ A[lastIndex--]=B[j--]; } }}
547.Intersection of Two Arrays:点击打开链接
public class Solution { /** * @param nums1 an integer array * @param nums2 an integer array * @return an integer array */ public int[] intersection(int[] nums1, int[] nums2) { //HashSet方法,time:O(n) Set<Integer> set=new HashSet<>(); Set<Integer> intersect=new HashSet<>(); for(int i=0;i<nums1.length;i++){ if(!set.contains(nums1[i])){ set.add(nums1[i]); } } for(int i=0;i<nums2.length;i++){ if(set.contains(nums2[i])){ intersect.add(nums2[i]); } } int[] result=new int[intersect.size()]; int i=0; for(Integer num:intersect){ result[i++]=num; } return result; }}
public class Solution { /** * @param nums1 an integer array * @param nums2 an integer array * @return an integer array */ public int[] intersection(int[] nums1, int[] nums2) { //Sort arrays方法,time:O(nlogn) Arrays.sort(nums1); //先sort Arrays.sort(nums2); Set<Integer> set=new HashSet<>(); int i=0,j=0; while(i<nums1.length && j<nums2.length){ if(nums1[i]<nums2[j]){ //哪个小哪个向前走一步 i++; }else if(nums[i]>nums2[j]){ j++; }else{ //两个相等的时候就加入到set,并且两个同时向前走一步 set.add(nums1[i]); i++; j++; } } int[] result=new int[set.size()]; int index=0; for(Integer num:set){ result[index++]=num; } return result; }}
public class Solution { /** * @param nums1 an integer array * @param nums2 an integer array * @return an integer array */ public int[] intersection(int[] nums1, int[] nums2) { //binarySearch方法,time:O(nlogn) if (nums1 == null || nums2 == null) { return null; } Set<Integer> set = new HashSet<>(); Arrays.sort(nums1); for (int i = 0; i < nums2.length; i++) { if (binarySearch(nums1, nums2[i])) { set.add(nums2[i]); } } int[] result = new int[set.size()]; int index = 0; for (Integer num : set) { result[index++] = num; } return result; } private boolean binarySearch(int[] nums,int target){ if(nums==null || nums.length==0){ return false; } int start=0, end=nums.length-1; while (start + 1 < end) { int mid=(end-start)/2+start; if(nums[mid]==target) { return true; } if(nums[mid]<target) { start = mid; }else { end = mid; } } if(nums[start]==target) { return true; } if(nums[end]==target) { return true; } return false; }}
548.Intersection of Two ArraysII : 点击打开链接
public class Solution { /** * @param nums1 an integer array * @param nums2 an integer array * @return an integer array */ public int[] intersection(int[] nums1, int[] nums2) { //输出所有的重复元素 if(nums1==null || nums2==null){ return null; } Arrays.sort(nums1); Arrays.sort(nums2); List<Integer> temp=new ArrayList<>(); //换成一个list乘装暂时的重复元素,再向数组里倒 int i=0,j=0; while(i<nums1.length && j<nums2.length){ if(nums1[i]<nums2[j]){ i++; }else if(nums1[i]>nums2[j]){ j++; }else{ temp.add(nums1[i]); i++; j++; } } int[] result=new int[list.size()]; int index=0; for(Integer num:list){ result[index++]=num; } return result; }}
65.Median of Two Sorted Arrays:点击打开链接
1. 如果数组A和B的总长度length是奇数,中位数就是第length / 2 + 1小的数,
如果length是偶数,中位数就是第length / 2小的数和length / 2 + 1小的数的平均数。
2. 要在两个排序的数组A和B(记成新数组)中找第k小的数,
我们希望用O(1)的时间把问题分解成:在数组A和数组B中分别找第k / 2小的数。
3. 我们比较数组A中第k / 2小的数和数组B中第k / 2小的数:
如果A[k / 2 - 1] < B[k / 2 - 1],说明在新数组中第k小的数不可能是A[k/2 - 1]以及这个数之前的数字,
那么我们可以把这k / 2个数字从A数组中踢掉,并在B数组和 过数的A数组里 分别找第k / 2小的数。
同理,如果B[k / 2 - 1] < A[k / 2 - 1],我们可以把k / 2个数字从B数组中踢掉,并在A数组和踢过数的B数组里分别找第k / 2小的数。
class Solution { /** * @param A: An integer array. * @param B: An integer array. * @return: a double whose format is *.5 or *.0 */ public double findMedianSortedArrays(int[] A, int[] B) { int length=A.length+B.length; if(length%2==0){ return (findKth(A,0,B,0,length/2)+findKth(A,0,B,0,length/2+1))/2.0; } return findKth(A,0,B,0,length/2+1); } private int findKth(int[] A,int startA,int[] B,int startB,int k){ if(startA>=A.length){ //如果A变成null,就成了B数组单独找Kth return B[startB+k-1]; } if(startB>=B.length){ //如果B变成null,就成了A数组单独找Kth return A[startA+k-1]; } if(k==1){ //如果找第一大的数,就是A,B数组中的第一个小值 return Math.min(A[startA],B[startB]); } int valueA=startA+k/2-1<A.length?A[startA+k/2-1]:Integer.MAX_VALUE; //哪个数组不够了,就用无穷大后面补全 int valueB=startB+k/2-1<B.length?B[startB+k/2-1]:Integer.MAX_VALUE; if(valueA<valueB){ return findKth(A,startA+k/2,B,startB,k-k/2); } return findKth(A,startA,B,startB+k/2,k-k/2); }}
41. Mixmam Subarray:点击打开链接
PrefixSum[i]=nums[0]+nums[1]+...+nums[i-1],PrefixSum[0]=0;
例如:int [ ] num={1,2,3,4,-5}
PrefixSum[0]=0,
PrefixSum[1]=nums[0]=1;
PrefixSum[2]=nums[0]+nums[1]=1+2=3;
PrefixSum[3]=nums[0]+nums[1]+nums[2]=1+2+3=6;
PrefixSum[4]=nums[0]+nums[1]+nums[2]+nums[3]=1+2+3+4=10;
PrefixSum[5]=nums[0]+nums[1]+nums[2]+nums[3]+nums[4]=1+2+3+4+(-5)=5;
public class Solution { /** * @param nums: A list of integers * @return: A integer indicate the sum of max subarray */ public int maxSubArray(int[] nums) { if(nums==null || nums.length==0){ return 0; } int sum=0; int maxVal=Integer.MIN_VALUE; int minSum=0; for(int i=0;i<nums.length;i++){ sum+=nums[i]; maxVal=Math.max(maxVal,sum-minSum); //每次拿到一个当前最大值,都要比较(当前最大值)与(当前sum-当前最小和)的小大 minSum=Math.min(minSum,sum); //如果当前sum-当前最小和,自然得到就是当前最大值 } return maxVal; }}
42. Maximum SubArray II: 点击打开链接
public class Solution { /** * @param nums: A list of integers * @return: An integer denotes the sum of max two non-overlapping subarrays */ public int maxTwoSubArrays(ArrayList<Integer> nums) { int maxVal=Integer.MIN_VALUE; int minSum=0; int sum=0; int[] left=new int[nums.size()]; for(int i=0;i<nums.size();i++){ //左边开始相加,left[i]表示到i当前的最大值 sum+=nums.get(i); maxVal=Math.max(maxVal,sum-minSum); minSum=Math.min(sum,minSum); left[i]=maxVal; } maxVal=Integer.MIN_VALUE; minSum=0; sum=0; int[] right=new int[nums.size()]; for(int i=nums.size()-1;i>=0;i--){ //右边开始相加,right[i]表示到i当前的最大值 sum+=nums.get(i); maxVal=Math.max(maxVal,sum-minSum); minSum=Math.min(sum,minSum); right[i]=maxVal; } maxVal=Integer.MIN_VALUE; for(int i=0;i<nums.size()-1;i++){ maxVal=Math.max(maxVal,left[i]+right[i+1]); //最后对每一个左边最大,与比它向后一个位置的右边最大的和取最大 } return maxVal; }}
138.Subarray Sum:点击打开链接
思路:子数组和为一个数,无非就是两种情况,从头开始的subarray,和从中间某一个位置开始的subarray
对于从中间某一位置i开始的subarray,例如前i位置之和为3,而从i+1 ~ j这一段加起来还是3,说明i+1 ~ j这段和为0
注意:如果需要计算子数组从下标i到下标j之间的所有数之和,则有:Sum(i~j)=PrefixSum[j+1]-PrefixSum[i]
public class Solution { /** * @param nums: A list of integers * @return: A list of integers includes the index of the first number * and the index of the last number */ public ArrayList<Integer> subarraySum(int[] nums) { //方法一 ArrayList<Integer> result=new ArrayList<>(); if(nums==null || nums.length==0){ return result; } Map<Integer,Integer> map=new HashMap<>(); int sum=0; for(int i=0;i<nums.length;i++){ sum+=nums[i]; if(!map.containsKey(sum)){ //从头开始的每一个preSum map.put(sum,i); if(sum==0){ result.add(0); result.add(i); break; } }else{ //非从头开始(中间段)的每一个preSum result.add(map.get(sum)+1); result.add(i); break; } } return result; }}
public class Solution { /** * @param nums: A list of integers * @return: A list of integers includes the index of the first number * and the index of the last number */ public ArrayList<Integer> subarraySum(int[] nums) { //方法二:同样思路 ArrayList<Integer> ans = new ArrayList<Integer>(); HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); map.put(0, -1); //先放入sum为0,位置为-1 int sum = 0; for (int i = 0; i <nums.length; i++) { sum += nums[i]; if (map.containsKey(sum)) { //有同样的sum出现,就取之前出现sum的前一个位置和当前sum位置 ans.add(map.get(sum) + 1); ans.add(i); return ans; } map.put(sum, i); //只要有新的sum就放入到sum和位置i,表示从0开始到i的这段sum } return ans; }}
560. Subarray Sum Equals K:点击打开链接
public class Solution { public int subarraySum(int[] nums, int k) { if(nums==null || nums.length==0){ return 0; } Map<Integer,Integer> map=new HashMap<>(); int result=0; int sum=0; map.put(0,1); //考虑到从头开始的情况,要先放入sum为0,次数为1,不然会空指针异常 for(int i=0;i<nums.length;i++){ sum+=nums[i]; if(map.containsKey(sum-k)){ //每到一个数 result+=map.get(sum-k); } map.put(sum,map.getOrDefault(sum,0)+1); //用map来保存当前数组从头开始的前i项和的次数 } return result; }}
public class Solution { public int subarraySum(int[] nums, int k) { //brute force方法 if(nums==null || nums.length==0){ return 0; } int count=0; for(int i=0;i<nums.length;i++){ int sum=0; sum+=nums[i]; if(sum==k){ count++; } for(int j=i+1;j<nums.length;j++){ sum+=nums[j]; if(sum==k){ count++; } } } return count; }}
139.Subarray Sum Closet: 点击打开链接
class Pair { int sum; int index; public Pair(int sum, int index) { this.sum = sum; this.index = index; }} public class Solution { /** * @param nums: A list of integers * @return: A list of integers includes the index of the first number * and the index of the last number */ public int[] subarraySumClosest(int[] nums) { int[] result=new int[2]; if(nums==null || nums.length==0){ return result; } int len=nums.length; if(len==1){ result[0]=result[1]=0; } Pair[] preSum=new Pair[len+1]; //preSum表示的是前i个元素和,和对应的索引i-1 int pre=0; //也就是preSum[3],前3个元素和,是0,1,2,因此索引是2 preSum[0]=new Pair(0,0); for(int i=1;i<=len;i++){ //for循环拿到前i个元素和 preSum[i]=new Pair(pre+nums[i-1],i); pre=preSum[i].sum; } Arrays.sort(preSum,new Comparator<Pair>(){ //然后重新排序preSum,按照和的大小 public int compare(Pair p1,Pair p2){ //因此重新排序后preSum表示的在数组preSum中第几大 return p1.sum-p2.sum; } }); int closet=Integer.MAX_VALUE; for(int i=1;i<=len;i++){ if(preSum[i].sum-preSum[i-1].sum<closet){ //两两一次遍历记录当前最小的差,也就是对应的索引差最接近0 closet=preSum[i].sum-preSum[i-1].sum; int[] temp=new int[]{preSum[i-1].index-1,preSum[i].index-1}; Arrays.sort(temp); result[0]=temp[0]+1; result[1]=temp[1]; } } return result; }}
- [Algorithm]九章六之二: Array
- Algorithm之路二十六:Remove Duplicates from Sorted Array
- [Algorithm]九章九之二:Sequence
- 漫谈 HMM之二:Forward-Backward Algorithm
- Algorithm之路二:Add Two Numbers
- Algorithm之路二十二:Generate Parentheses
- Algorithm之路二十七:Remove Element
- Algorithm: Array(1)
- 算法之旅,直奔<algorithm>之二 adjacent_find
- 算法之旅,直奔<algorithm>之二十 make_heap
- 算法之旅,直奔<algorithm>之二十一 max
- 算法之旅,直奔<algorithm>之二十二 sort
- 算法之旅,直奔<algorithm>之二十三 none_of
- ACM竞赛常用STL(二)之STL--algorithm
- ACM竞赛常用STL(二)之STL--algorithm
- 八年程序员之书籍篇--Algorithm(二):算法盒子
- Algorithm之路二十一:Merge Two Sorted Lists
- Algorithm之路二十三:Merge k Sorted Lists
- SpringMVC工作原理
- c++11新特性总结和boost库的使用
- mysql---数据排序检索
- 贪心总论
- Http返回状态码
- [Algorithm]九章六之二: Array
- 贪心之活动选择问题
- Leetcode 18. 4Sum
- 比特币合同
- [Algorithm]九章七:Two Pointer
- [Algorithm]九章八:Data Structure
- [Algorithm] Palindrome 问题
- VC编译调试比特币源码
- 自定义View环形递增