给定一个整数数组,判断是否存在重复元素。
如果存在一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false 。
示例 1:
输入: [1,2,3,1]
输出: true
示例 2:
输入: [1,2,3,4]
输出: false
示例 3:
输入: [1,1,1,3,3,4,3,2,4,2]
输出: true
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/contains-duplicate
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
package lk2021_03_22;
import java.util.HashMap;
public class Main {
public boolean containsDuplicate(int[] nums) {
HashMap<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
if(!map.containsKey(nums[i])) {
map.put(nums[i], 1);
}else {
int temp = map.get(nums[i]);
map.put(nums[i], temp+1);
}
}
for (int i = 0; i < nums.length; i++) {
if(map.get(nums[i])>1) {
return true;
}
}
return false;
}
}
package lk2021_03_22;
import java.util.HashSet;
public class Main4 {
public boolean containsDuplicate(int[] nums) {
HashSet<Integer> set = new HashSet<>();
for (int i = 0; i < nums.length; i++) {
set.add(nums[i]);
}
return set.size()!=nums.length;
}
}
不使用任何内建的哈希表库设计一个哈希集合(HashSet)。
实现 MyHashSet 类:
void add(key) 向哈希集合中插入值 key 。
bool contains(key) 返回哈希集合中是否存在这个值 key 。
void remove(key) 将给定值 key 从哈希集合中删除。如果哈希集合中没有这个值,什么也不做。
示例:
输入:
[“MyHashSet”, “add”, “add”, “contains”, “contains”, “add”, “contains”, “remove”, “contains”]
[[], [1], [2], [1], [3], [2], [2], [2], [2]]
输出:
[null, null, null, true, false, null, true, null, false]
解释:
MyHashSet myHashSet = new MyHashSet();
myHashSet.add(1); // set = [1]
myHashSet.add(2); // set = [1, 2]
myHashSet.contains(1); // 返回 True
myHashSet.contains(3); // 返回 False ,(未找到)
myHashSet.add(2); // set = [1, 2]
myHashSet.contains(2); // 返回 True
myHashSet.remove(2); // set = [1]
myHashSet.contains(2); // 返回 False ,(已移除)
提示:
0 <= key <= 106
最多调用 104 次 add、remove 和 contains 。
进阶:你可以不使用内建的哈希集合库解决此问题吗?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/design-hashset
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:建立一个key范围的boolean数组,所有操作变成对数组的布尔值操作
class MyHashSet {
/** Initialize your data structure here. */
boolean[] hash;
public MyHashSet() {
hash = new boolean[1000001];
}
public void add(int key) {
if(hash[key]==false){
hash[key]=true;
}
}
public void remove(int key) {
if(hash[key]){
hash[key]=false;
}
}
/** Returns true if this set contains the specified element */
public boolean contains(int key) {
if(hash[key]){
return true;
}
return false;
}
}
/**
* Your MyHashSet object will be instantiated and called as such:
* MyHashSet obj = new MyHashSet();
* obj.add(key);
* obj.remove(key);
* boolean param_3 = obj.contains(key);
*/
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
说明:
你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
package lk2021_03_22;
import java.util.Collections;
import java.util.PriorityQueue;
public class Main5 {
public int findKthLargest(int[] nums, int k) {
//最大堆
PriorityQueue<Integer> heap = new PriorityQueue<>(Collections.reverseOrder());
for (int i = 0; i < nums.length; i++) {
heap.add(nums[i]);
}
while (k>1) {
heap.poll();
k--;
}
return heap.peek();
}
}
给一非空的单词列表,返回前 k 个出现次数最多的单词。
返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率,按字母顺序排序。
示例 1:
输入: [“i”, “love”, “leetcode”, “i”, “love”, “coding”], k = 2
输出: [“i”, “love”]
解析: “i” 和 “love” 为出现次数最多的两个单词,均为2次。
注意,按字母顺序 “i” 在 “love” 之前。
示例 2:
输入: [“the”, “day”, “is”, “sunny”, “the”, “the”, “the”, “sunny”, “is”, “is”], k = 4
输出: [“the”, “is”, “sunny”, “day”]
解析: “the”, “is”, “sunny” 和 “day” 是出现次数最多的四个单词,
出现次数依次为 4, 3, 2 和 1 次。
注意:
假定 k 总为有效值, 1 ≤ k ≤ 集合元素数。
输入的单词均由小写字母组成。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/top-k-frequent-words
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
package lk2021_03_22;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.PriorityQueue;
public class Main6 {
public List<String> topKFrequent(String[] words, int k) {
HashMap<String, Integer> map = new HashMap<>();
for (int i = 0; i < words.length; i++) {
if(map.containsKey(words[i])) {
int temp =map.get(words[i]);
map.put(words[i], temp+1);
}
else {
map.put(words[i], 1);
}
}
//频数越大,字母越小的越在堆顶
PriorityQueue<String> heap = new PriorityQueue<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
// TODO 自动生成的方法存根
return map.get(o1)==map.get(o2) ? o1.compareTo(o2) : -(map.get(o1)-map.get(o2));
}
});
for(String word:map.keySet()) {
heap.add(word);
}
List<String> res = new ArrayList<String>();
while(k>0) {
res.add(heap.poll());
k--;
}
return res;
}
}
package lk2021_03_22;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.PriorityQueue;
public class Main7 {
public List<String> topKFrequent(String[] words, int k) {
HashMap<String, Integer> map = new HashMap<>();
for(String word:words) {
if(map.containsKey(word)) {
int temp = map.get(word)+1;
map.put(word, temp);
}
else {
map.put(word, 1);
}
}
//小顶堆,让比较情况和需要的情况反过来
//频数越小越在堆顶,字母越大越先
PriorityQueue<String> heap = new PriorityQueue<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return map.get(o1)==map.get(o2)?o2.compareTo(o1):map.get(o1)-map.get(o2);
}
});
for(String word:map.keySet()) {
heap.add(word);
if(heap.size()>k) {
heap.poll();
}
}
List<String> res = new ArrayList<String>();
while (!heap.isEmpty()) {
res.add(heap.poll());
}
//反转过来,字母越小的越先
Collections.reverse(res);
return res;
}
}
给定一个链表,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true 。 否则,返回 false 。
进阶:
你能用 O(1)(即,常量)内存解决此问题吗?
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
提示:
链表中节点的数目范围是 [0, 104]
-105 <= Node.val <= 105
pos 为 -1 或者链表中的一个 有效索引 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/linked-list-cycle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
if(head==null){
return false;
}
ListNode slow=head;
ListNode fast=head;
while(fast!=null && fast.next!=null){
slow=slow.next;
fast=fast.next.next;
if(slow==fast){
return true;
}
}
return false;
}
}
第 i 个人的体重为 people[i],每艘船可以承载的最大重量为 limit。
每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit。
返回载到每一个人所需的最小船数。(保证每个人都能被船载)。
示例 1:
输入:people = [1,2], limit = 3
输出:1
解释:1 艘船载 (1, 2)
示例 2:
输入:people = [3,2,2,1], limit = 3
输出:3
解释:3 艘船分别载 (1, 2), (2) 和 (3)
示例 3:
输入:people = [3,5,3,4], limit = 5
输出:4
解释:4 艘船分别载 (3), (3), (4), (5)
提示:
1 <= people.length <= 50000
1 <= people[i] <= limit <= 30000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/boats-to-save-people
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:先排序,再利用对撞双指针法,和两数之和有点类似的感觉,但提交后发现时间效率不算高
package lk2021_03_22;
import java.util.Arrays;
public class Main9 {
public int numRescueBoats(int[] people, int limit) {
//边界
if(people==null||people.length==0) {
return 0;
}
int res = 0;
//先排序
Arrays.sort(people);
int l=0;
int r=people.length-1;
while (l<=r) {
if(people[l]+people[r]<=limit) {
l++;
}
r--;
res+=1;
}
return res;
}
}