public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (map.containsKey(complement)) {
return new int[] { map.get(complement), i };
}
map.put(nums[i], i);
}
throw new IllegalArgumentException("No two sum solution");
}
复杂度分析:
时间复杂度:O(n)O(n), 我们只遍历了包含有 nn 个元素的列表一次。在表中进行的每次查找只花费 O(1)O(1) 的时间。
空间复杂度:O(n)O(n), 所需的额外空间取决于哈希表中存储的元素数量,该表最多需要存储 nn 个元素。
2、三数之和
题解:
* a.我们可以先将原数组从小到大排序,固定其中两个元素 i 和 j,i从前往后走,j从后往前走,i 每往后一个,将 j 重置为数组末尾的下标,在 i 和 j
* 之间找使nums[i] +nums[j] +nums[k] == 0成立的k。
*<p>
* b.如何去重:每次得出nums[i] +nums[j] +nums[k] == 0成立的i、j、k之后,令 i 往后走,直到nums[i] !=
public int findKthLargestMy(int[] nums, int k) {
PriorityQueue<Integer> pq = new PriorityQueue<>(); // 小顶堆
for (int val : nums) {
pq.add(val);
if (pq.size() > k) // 维护堆的大小为 K
pq.poll();
}
return pq.peek();
}
c、快速选择 :时间复杂度 O(N),空间复杂度 O(1)
public int findKthLargest(int[] nums, int k) {
int begin=0;
int end=nums.length-1;
k=nums.length+1-k;
while(begin<end){
int pos=partition(nums,begin,end);
if(pos==k-1) break;
else if(pos<k-1) begin=pos+1;
else end=pos-1;
}
return nums[k-1];
}
public int partition(int[]nums,int l,int r){
int less=l-1;//小于区的下标
int more=r;//大于区的下标,默认以最后一个下标的数作为划分值
while(l<more){
if(nums[l]<nums[r])
swap(nums,++less,l++);
else if (nums[l]>nums[r])
swap(nums,--more,l);
else l++;
}
swap(nums,more,r);
return less+1;//小于区位置+1可以得到划分的这个数的下标
}
private void swap(int[] a, int i, int j) {
int t = a[i];
a[i] = a[j];
a[j] = t;
}