水塘抽样
Linked List Random Node
Given a singly linked list, return a random node’s value from the linked list. Each node must have the same probability of being chosen.
Follow up:
What if the linked list is extremely large and its length is unknown to you? Could you solve this efficiently without using extra space?
Example:1
2
3
4
5
6
7
8// Init a singly linked list [1,2,3].
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
Solution solution = new Solution(head);
// getRandom() should return either 1, 2, or 3 randomly. Each element should have equal probability of returning.
solution.getRandom();
1 | /** |
Random Pick Index
Given an array of integers with possible duplicates, randomly output the index of a given target number. You can assume that the given target number must exist in the array.
Note:
The array size can be very large. Solution that uses too much extra space will not pass the judge.
Example:1
2
3
4
5
6
7
8int[] nums = new int[] {1,2,3,3,3};
Solution solution = new Solution(nums);
// pick(3) should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning.
solution.pick(3);
// pick(1) should return 0. Since in the array only nums[0] is equal to 1.
solution.pick(1);
1 | class Solution { |
线段树
Count of Smaller Numbers After Self
You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i].
Example:1
2
3
4
5
6
7Input: [5,2,6,1]
Output: [2,1,1,0]
Explanation:
To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.
1 | // 此题先用二分查找树实现,线段树实现方法之后正在更新 |
最大公约数
1 | int gcd(int a, int b) { |
子串和满足条件的最短长度
Minimum Size Subarray Sum
Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn’t one, return 0 instead.
Example:1
2
3Input: s = 7, nums = [2,3,1,2,4,3]
Output: 2
Explanation: the subarray [4,3] has the minimal length under the problem constraint.
1 | class Solution { |
上一题数组中包含正负,找和为target的最小长度
1 |
|
上一题的follow up,包含正负,找出大于等于k的最小长度
Return the length of the shortest, non-empty, contiguous subarray of A with sum at least K.
If there is no non-empty subarray with sum at least K, return -1.
Example 1:1
2Input: A = [1], K = 1
Output: 1
Example 2:1
2Input: A = [1,2], K = 4
Output: -1
Example 3:1
2Input: A = [2,-1,2], K = 3
Output: 3
1 |
|
快排相关
快排模板
1 |
|
快排优化
快排的优化可以参考此处文献
基准随机化算法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using namespace std;
int partition(vector<int>& nums, int left, int right) {
int base = nums[left];
while (left < right) {
while (left < right && nums[right] >= base) right --;
if (left < right) nums[left] = nums[right];
while (left < right && nums[left] < base) left ++;
if (left < right) nums[right] = nums[left];
}
nums[left] = base;
return left;
}
void helper(vector<int>& nums, int left, int right) {
if (left < right) {
// 随机产生基准
int index = left + rand() % (right - left + 1);
swap(nums[left], nums[right]);
int mid = partition(nums, left, right);
helper(nums, left, mid - 1);
helper(nums, mid + 1, right);
}
}
int main() {
int n;
cin >> n;
vector<int> nums(n, 0);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
helper(nums, 0, n - 1);
for (int i : nums) {
cout << i << endl;
}
return 0;
}将前后中间三个数取中值作为标兵元素
- 在数组大小等于一定范围的时候,改为插入排序,防止排序退化
- 将相等的数字聚集到一起,然后跳过此处的排序
快速选择算法模板
验证地址Leetcode 215
1 |
|
快速选择算法复杂度为O(n)的证明
最大子串和
贪心算法,最小类似
1 |
|
并查集模板
1 |
|
牛顿法
Implement int sqrt(int x).
Compute and return the square root of x, where x is guaranteed to be a non-negative integer.
Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.
Example 1:1
2Input: 4
Output: 2
Example 2:1
2
3
4Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since
the decimal part is truncated, 2 is returned.
1 | class Solution { |
堆排序
1 |
|
拓扑排序
1 |
|
快速幂
Pow(x, n)
Implement pow(x, n), which calculates x raised to the power n (xn).
1 | Input: 2.00000, 10 |
代码
1 | class Solution { |
矩阵快速幂
矩阵乘法还可以做dp优化,之后更新….
1 |
|
全排列相关
Permutation Sequence
对于数字全排列可以用这种方法
1 | string getPermutation(int n, int k) { |
字母全排列
数字可以用上面的方法,但是对于字母来说就不行了,因为long long也存不下所有全排列的种类数
第二个思路是使用nextPermutation,此函数的原理是
- 从最后向前找相邻的两个元素是的i < ii
- 然后再从最后向前找一个元素使得i < j
- i和j交换,然后将ii之后的元素reverse排序
nextPermutation的头文件是algorithm
1 | string getPermutation(int n, int k) { |
面试题集合
面试题1
一个树形的图,要遍历其中k个节点,最少需要走多少步
1 |
|
面试题2
表达式求值
1 |
|
面试题3
寻找能使数组跷跷板平衡的支点有几个
1 |
|
面试题4
给定一组数,表示他所在组的大小,输出一个数组,同一分组的在一起,数组保证字典序最小
1 |
|
面试题5
题目:给定一个状态转移图,和一个目标字符集合
M=
| |A |B |C |
|—-|:–:|:–:|:–:|
|A |B,C |C |A |
|B |A,C |C |C |
|C |A |A |A,B |
S={A,B,C}
每两个字符可以转换成一个字符,例如AAB可以转成BC,判断是否能最后转化成目标集合中的字符
1 |
|