精品推荐:
《征服数据结构》专栏:50多种数据结构彻底征服
《经典图论算法》专栏:50多种经典图论算法全部掌握
Question: Suppose you have a 4 liter jug and a 9 liter bucket . The buckets have no measurement lines on them either. How could you measure exactly 6 liter using only those buckets and you have as much extra water as you need ?
这题是微软的一道逻辑面试题,问的是给你一个 4L 和一个 9L 的桶,桶上没有刻度,怎么才能精确的量出 6L 的水,量的时候可以提供足够的水让你使用。
思考一下,两小时后答案会放到评论区。
--------------下面是今天的算法题--------------
来看下今天的算法题,这题是LeetCode的第219题:存在重复元素 II。
问题描述
来源:LeetCode第219题
难度:简单
给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个不同的索引 i 和 j ,满足 nums[i] == nums[j] 且 abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false 。
示例1:
输入:nums = [1,2,3,1], k = 3
输出:true
示例2:
输入:nums = [1,0,1,1], k = 1
输出:true
1 <= nums.length <= 10^5
-10^9 <= nums[i] <= 10^9
0 <= k <= 10^5
问题分析
这题是判断数组中是否有重复的元素,不过这里有个限制,就是两个相同元素的下标差不能超过 k 。
实际上这是一道滑动窗口问题,窗口的大小是k+1,如果超过这个限制,就把最先添加的给移除。也就是说在窗口中任何两个元素的下标差都不会超过 k ,我们只需要判断窗口中是否有重复的元素即可。
JAVA:
public boolean containsNearbyDuplicate(int[] nums, int k) {
// windowSet相当于一个窗口,窗口的大小是k+1
Set<Integer> windowSet = new HashSet<>();
for (int i = 0; i < nums.length; i++) {
// 如果窗口中的元素个数超过k+1(注意 i 的下标是从 0 开始的),
// 就把最前面的给移除
if (i > k)
windowSet.remove(nums[i - k - 1]);
// 这个时候窗口中的元素都是不超过k+1的,把当前元素添加到
// 窗口中,如果有重复的,add方法回返回false。
if (!windowSet.add(nums[i]))
return true;
}
return false;
}
C++:
public:
bool containsNearbyDuplicate(vector<int>& nums, int k) {
// s 相当于一个窗口,窗口的大小是k+1
unordered_set<int> s;
for (int i = 0; i < nums.size(); i++) {
// 如果窗口中的元素个数超过k+1(注意 i 的下标是从 0 开始的),
// 就把最前面的给移除
if (i > k)
s.erase(nums[i - k - 1]);
// 这个时候窗口中的元素都是不超过k+1的,把当前元素添加到
// 窗口中,如果有重复的,直接返回。
if (!s.insert(nums[i]).second)
return true;
}
return false;
}
Python:
def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
# windowSet相当于一个窗口,窗口的大小是k + 1
s = set()
for index, val in enumerate(nums):
# 如果窗口中的元素个数超过k + 1(注意 i 的下标是从 0 开始的),
# 就把最前面的给移除
if index > k:
s.remove(nums[index - k - 1])
# 这个时候窗口中的元素都是不超过k+1的,把当前元素添加到
# 窗口中,如果有重复的,直接返回
if val in s: # 有重复的直接返回true
return True
s.add(val)
return False
笔者简介
博哥,真名:王一博,毕业十多年,《算法秘籍》作者,专注于数据结构和算法的讲解,在全球30多个算法网站中累计做题2000多道,在公众号中写算法题解800多题,对算法题有自己独特的解题思路和解题技巧,喜欢的可以给个关注,也可以下载我整理的1000多页的PDF算法文档。
数组,稀疏表(Sparse Table),单向链表,双向链表,块状链表,跳表,队列和循环队列,双端队列,单调队列,栈,单调栈,双端栈,散列表,堆,字典树(Trie树),ArrayMap,SparseArray,二叉树,二叉搜索树(BST),笛卡尔树,AVL树,树堆(Treap),FHQ-Treap
……
图的介绍,图的表示方式,邻接矩阵转换,广度优先搜索(BFS),深度优先搜索(DFS),A*搜索算法,迭代深化深度优先搜索(IDDFS),IDA*算法,双向广度优先搜索,迪杰斯特拉算法(Dijkstra),贝尔曼-福特算法(Bellman-Ford),SPFA算法,弗洛伊德算法(Floyd)
……