题目一
一个手链有m个珠子共n种颜色,找出包含n种颜色的最短连续片段。例如手链[1,2,2,2,2,2,2,0],它的最短连续片段数为3。
暴力破解
遍历所有可能性,时间复杂度 O ( m n 2 ) O(mn^2) O(mn2)
方法一
使用双指针的方法,记为 s t a r t = 0 start=0 start=0、 e n d = 0 end=0 end=0:
- 向右移动 e n d end end,直到 [ s t a r t , e n d ] [start, end] [start,end]中包含 m m m种颜色的珠子
- 循环
- s t a r t + = 1 start += 1 start+=1
- 若 [ s t a r t , e n d ] [start, end] [start,end]中,包含 m m m种颜色的珠子,更新最小值
- 若 [ s t a r t , e n d ] [start, end] [start,end]中,小于 m m m种颜色的珠子,移动 e n d end end
- 终止
具体代码如下所示
from collections import defaultdict
def get_length(cate2num):
return len([cate for cate, num in cate2num.items() if num != 0])
def function(input_array, m, n):
head, tail = 0, 0
min_size = 1e10
length = len(input_array)
cate2num = defaultdict(int)
while(head < len(input_array)):
# 更新tail指针
while(get_length(cate2num) != n):
index = tail % length
cate2num[input_array[index]] += 1
tail += 1
# 更新head指针
min_size = min(min_size, tail - head)
# 更新数值
cate2num[input_array[head]] -= 1
head += 1
return min_size
题目二
有m个米家,n个米粉,求这些米粉到米家的最短距离。为了简化问题,假设所有这些设施都在一条直线,例如米家为 [ 5 , 3 , 2 ] [5,3,2] [5,3,2],米粉为 [ 1 , 3 , 4 ] [1,3,4] [1,3,4],此时最短距离为 2 2 2。
方法
将米家和米粉分别排序,然后从左往右、从右往左遍历两遍,两个数组最小值加和即为结果。
代码
def min_size(shops, customers):
shops = sorted(shops)
customers = sorted(customers)
# 从左到右
j, left_buff = 0, []
for i in range(len(customers)):
# 更新
while(j < len(shops) and customers[i] > shops[j]):
j += 1
left_buff.append(shops[j] - customers[i] if j < len(shops) else 1e10)
# 从右到左
j, right_buff = len(shops) - 1, []
for i in range(len(customers) - 1, -1, -1):
# 更新
while(j >= 0 and customers[i] < shops[j]):
j -= 1
right_buff.append(customers[i] - shops[j] if j >= 0 else 1e10)
right_buff = right_buff[::-1]
return sum([min(l, r) for l, r in zip(right_buff, left_buff)])
题目三
给定一个非降序列 i n p u t _ a r r a y input\_array input_array和一个数值 v v v,请给出 i n p u t _ a r r a y input\_array input_array中 v v v的下一个元素的 i n d e x index index。例如 [ 1 , 2 , 2 , 2 , 3 ] [1,2,2,2,3] [1,2,2,2,3]返回值为 4 4 4。
方法
二分查找,迭代更新
代码
def func(input_array, m):
# 边界条件
if(m < input_array[0]):
return -1
if(m >= input_array[-1]):
return -1
# 二分查找
start, end = 0, len(input_array) - 1
while(start <= end):
mid = int((start + end) / 2)
if(input_array[mid] < m):
start = mid + 1
continue
elif(input_array[mid] > m):
end = mid - 1
continue
elif(input_array[mid] == m and input_array[mid] == input_array[mid + 1]):
start = mid + 1
end = len(input_array) - 1
else:
return mid + 1
return -1
题目四
深度遍历/广度遍历/前序遍历/中序遍历
方法
略
代码
深度遍历/前序遍历(非递归)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> preorderTraversal(TreeNode* root) {
vector<int> result;
if(root == NULL)
return result;
stack<TreeNode*> storage;
storage.push(root);
while(storage.size() != 0){
TreeNode* pointer = storage.top();
storage.pop();
result.push_back(pointer -> val);
if(pointer -> right != NULL)
storage.push(pointer -> right);
if(pointer -> left != NULL)
storage.push(pointer -> left);
}
return result;
}
};
广度遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> levelOrder(TreeNode* root) {
vector<vector<int>> result;
if(root == NULL)
return result;
queue<TreeNode*> storage;
storage.push(root);
while(storage.size() != 0){
vector<int> buff;
int size = storage.size();
for(int i=0; i<size; i++){
TreeNode* pointer = storage.front();
storage.pop();
buff.push_back(pointer -> val);
if(pointer -> left != NULL)
storage.push(pointer -> left);
if(pointer -> right != NULL)
storage.push(pointer -> right);
}
result.push_back(buff);
}
return result;
}
};
中序遍历
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
stack<TreeNode*> storage;
TreeNode* pointer = root;
while(pointer != NULL || storage.size() != 0){
if(pointer == NULL){
pointer = storage.top();
storage.pop();
result.push_back(pointer -> val);
pointer = pointer -> right;
}else{
storage.push(pointer);
pointer = pointer -> left;
}
}
return result;
}
};