赞
踩
题目地址
描述
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任一一个重复的数字。 例如,如果输入长度为7的数组[2,3,1,0,2,5,3],那么对应的输出是2或者3。存在不合法的输入的话输出-1
数据范围:0 ≤ n ≤10000
进阶:时间复杂度0(n),空间复杂度0(n)
示例1
输入:
[2,3,1,0,2,5,3]
返回值:
2
说明:
2或3都是对的
代码
采用哈希数组arr,arr[element]=count表示元素element出现次数为count
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param numbers int整型一维数组 * @return int整型 */ public int duplicate (int[] numbers) { // write code here int[] arr=new int[numbers.length]; for(int i=0;i<numbers.length;i++){ arr[numbers[i]]++; if(arr[numbers[i]]>=2){ return numbers[i]; } } return -1; } }
题目地址
描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P mod 1000000007
数据范围:
对于 50% 的数据, size ≤ 10^4
对于100的数据, size ≤ 10^5
数组中所有数字的值满足0 ≤ val ≤ 1000000
要求:空间复杂度 O(n),时间复杂度 O(nlogn)
输入描述:
题目保证输入的数组中没有的相同的数字
示例1
输入:
[1,2,3,4,5,6,7,0]
返回值:
7
示例2
输入:
[1,2,3]
返回值:
0
算法思路
此处采用归并排序的方法,不知道的小伙伴可以先了解下~
首先简单介绍下归并排序:
归并排序讲究先分后并
先分:将数组分为两个子数组,子数组继续往下分,直到不能再分。
后并:从最小的数组按照顺序合并,从小到大或从大到小依次向上合并,直到获得最后的数组。
利用归并的方法进行统计分析,主要是在合并的时候统计。
例如:
在合并 {4 ,5} {1 , 2} 的时候,首先我们判断 1 < 4,此时统计出逆序对为2。这利用了数组的部分有序性。因为我们知道 {4 ,5} 这个数组必然是有序的,因为是合并上来的。此时当 1比4小的时候,证明4以后的数也都比1大,此时就构成了从4开始到 {4,5}这个数组结束,这么多个逆序对(2个),此时利用一个临时数组,将1存放起来,接着比较2和4的大小,同样可以得到有2个逆序对,于是将2也放进临时数组中,此时右边数组已经完全没有元素了,则将左边剩余的元素全部放进临时元素中,最后将临时数组中的元素放进原数组对应的位置。
(以上借鉴牛客Dylan博主的思路分享)
代码
public class Solution { public int InversePairs(int [] array) { int mod=1000000007; return InversePairs(array,0,array.length-1,mod); } public int InversePairs(int[] array,int l,int r,int mod){ while(l<r){ int mid=(l+r)/2; return (InversePairs(array,l,mid,mod)%mod +InversePairs(array,mid+1,r,mod)%mod +merge(array,l,mid,r,mod)%mod)%mod; } return 0; } public int merge(int[] array,int l,int mid,int r,int mod){ int i=l,j=mid+1; int index=0; int[] kept=new int[r-l+1]; int res=0; while(i<=mid&&j<=r){ if(array[i]<=array[j]){ kept[index++]=array[i]; i++; }else{ res=(res+(mid-i+1)%mod)%mod; kept[index++]=array[j]; j++; } } while(i<=mid){ kept[index++]=array[i++]; } while(j<=r){ kept[index++]=array[j++]; } for(int k=0;k<kept.length;k++){ array[k+l]=kept[k]; } return res; } }
题目地址
描述
给定一个长度为 n 的可能有重复值的数组,找出其中不去重的最小的 k 个数。例如数组元素是4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4(任意顺序皆可)。
数据范围:0≤k,n≤10000,数组中每个数的大小0≤val≤1000
要求:空间复杂度 O(n) ,时间复杂度 O(nlogn)
示例1
输入:
[4,5,1,6,2,7,3,8],4
返回值:
[1,2,3,4]
说明:
返回最小的4个数即可,返回[1,3,2,4]也可以
示例2
输入:
[1],0
返回值:
[]
示例3
输入:
[0,1,2,1,2],3
返回值:
[0,1,1]
代码
方法一:升序排序,然后找出最小的k个。
方法二:利用堆,设置一个大顶堆maxHeap,遍历数组中的元素,如果遍历到元素elem:
遍历结束后,栈中存放的就是前k小的元素。
import java.util.*; public class Solution { public ArrayList<Integer> GetLeastNumbers_Solution(int [] input, int k) { return GetLeastNumbers2(input,k); } //方法一:排序 public ArrayList<Integer> GetLeastNumbers1(int[] input,int k){ Integer[] a=new Integer[input.length]; for(int i=0;i<input.length;i++){ a[i]=input[i]; } Arrays.sort(a,new Comparator<Integer>(){ public int compare(Integer o1,Integer o2){ return o1-o2; } }); ArrayList<Integer> res=new ArrayList(); for(int i=0;i<k;i++){ res.add(a[i]); } return res; } //方法二:大顶堆 维持大小最大为k public ArrayList<Integer> GetLeastNumbers2(int[] input,int k){ ArrayList<Integer> res=new ArrayList<>(); if(input==null || k<=0){ return res; } PriorityQueue<Integer> maxheap=new PriorityQueue<>(new Comparator<Integer>(){ public int compare(Integer o1,Integer o2){ return o2-o1; } }); for(int i=0;i<input.length;i++){ if(maxheap.size()<k){ maxheap.add(input[i]); }else if(maxheap.peek()>input[i]){ maxheap.poll(); maxheap.add(input[i]); } } while(!maxheap.isEmpty()){ res.add(maxheap.poll()); } return res; } }
题目地址
描述
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
数据范围:数据流中数个数满足1 ≤ n ≤ 1000 ,大小满足 1 ≤ val ≤ 1000
进阶: 空间复杂度0(n) , 时间复杂度 0(nlogn)
示例1
输入:
[5,2,3,4,1,6,7,0,8]
返回值:
"5.00 3.50 3.00 3.50 3.00 3.50 4.00 3.50 4.00 "
说明:
数据流里面不断吐出的是5,2,3...,则得到的平均数分别为5,(5+2)/2,3...
示例2
输入:
[1,1,1]
返回值:
"1.00 1.00 1.00 "
代码
方法一:先排序然后找出中位数,代码略
方法二:采用大顶堆maxHeap 和小顶堆minHeap的方法,小顶堆存放一半的元素,大顶堆存放另一半,若无法平分,大顶堆多存一个。
import java.util.*; public class Solution { private PriorityQueue<Integer> minHeap=new PriorityQueue<>((o1,o2)->o1-o2);//right(1/2) private PriorityQueue<Integer> maxHeap=new PriorityQueue<>((o1,o2)->o2-o1);//left(1/2 + 1) public void Insert(Integer num) { if(maxHeap.isEmpty() || num<maxHeap.peek()){ maxHeap.add(num); }else{ minHeap.add(num); } if(maxHeap.size() == minHeap.size() + 2) minHeap.add(maxHeap.poll()); if(minHeap.size() == maxHeap.size() + 2) maxHeap.add(minHeap.poll()); } public Double GetMedian() { if(maxHeap.size() != minHeap.size()){ return maxHeap.size()>minHeap.size()?((double)maxHeap.peek()):((double)minHeap.peek()); }else{ return ((double)maxHeap.peek()+(double)minHeap.peek())/2.0; } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。