Create 面试总结.md
把自己平时面试的笔试算法题目做一个整理记录,方便以后查阅。
This commit is contained in:
parent
52a6800c10
commit
3d344ea1ce
126
notes/面试总结.md
Normal file
126
notes/面试总结.md
Normal file
@ -0,0 +1,126 @@
|
||||
<!-- GFM-TOC -->
|
||||
* [1. 字符串组合](#1-字符串组合)
|
||||
* [2. 实现 Singleton](#2-实现-singleton)
|
||||
* [3. 数组中重复的数字](#3-数组中重复的数字)
|
||||
|
||||
* [参考文献](#参考文献)
|
||||
<!-- GFM-TOC -->
|
||||
|
||||
# 1. 字符串组合
|
||||
|
||||
## 题目描述
|
||||
|
||||
给定三种类型的小球P、Q、R,每种小球的数量分别为np、nq、nr个。现在想讲这些小球排成一条直线,但是不允许相同类型的小球相邻,问有多少种排序方法。
|
||||
如若np=2,nq=1,nr=1则共有6种排列方式:PQRP、QPRP、PRQP、PRPQ、RPQP以及PQPR。如果无法组合出合适的结果,则输出0.
|
||||
|
||||
### 输入
|
||||
```code
|
||||
一行以空格相隔的三个数,分别表示为np、nq、nr。
|
||||
```
|
||||
|
||||
### 输出
|
||||
```code
|
||||
排列方法的数量。
|
||||
```
|
||||
|
||||
### 样例输入
|
||||
```code
|
||||
2 1 1
|
||||
```
|
||||
|
||||
### 样例输出
|
||||
```code
|
||||
6
|
||||
```
|
||||
|
||||
## 解题思路
|
||||
本题采用一种比较直接的方式进行解题,分为如下步骤:
|
||||
1. 求解给定P、Q、R个数的时候的全排列,提供`Python`提供的`itertools.permutations`来实现,此时肯定有很多重复。
|
||||
2. 去掉重复的情况,通过`Python`提供的`set`来实现。
|
||||
3. 通过遍历找出相邻元素重复的串。
|
||||
4. 求两个集合的差集,即为答案。
|
||||
|
||||
```python
|
||||
import itertools
|
||||
|
||||
|
||||
np, nq, nr = [int(k) for k in raw_input().split(" ")]
|
||||
|
||||
count = 0
|
||||
result = []
|
||||
|
||||
for i in itertools.permutations("P"*np + "Q"*nq + "R"*nr,np + nq + nr):
|
||||
result.append(''.join(i))
|
||||
|
||||
result_same = []
|
||||
|
||||
for element in list(set(result)):
|
||||
for j in range(1, len(element)):
|
||||
if element[j-1] == element[j]:
|
||||
result_same.append(element)
|
||||
|
||||
ret_list = list(set(result)^set(result_same))
|
||||
|
||||
print len(ret_list)
|
||||
```
|
||||
|
||||
|
||||
# 2. 实现 Singleton
|
||||
|
||||
[单例模式](https://github.com/CyC2018/Interview-Notebook/blob/master/notes/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F.md)
|
||||
|
||||
# 3. 数组中重复的数字
|
||||
|
||||
[NowCoder](https://www.nowcoder.com/practice/623a5ac0ea5b4e5f95552655361ae0a8?tpId=13&tqId=11203&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking)
|
||||
|
||||
## 题目描述
|
||||
|
||||
在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道每个数字重复几次。请找出数组中任意一个重复的数字。例如,如果输入长度为 7 的数组 {2, 3, 1, 0, 2, 5},那么对应的输出是第一个重复的数字 2。
|
||||
|
||||
要求复杂度为 O(N) + O(1),也就是时间复杂度 O(N),空间复杂度 O(1)。因此不能使用排序的方法,也不能使用额外的标记数组。牛客网讨论区这一题的首票答案使用 nums[i] + length 来将元素标记,这么做会有加法溢出问题。
|
||||
|
||||
## 解题思路
|
||||
|
||||
这种数组元素在 [0, n-1] 范围内的问题,可以将值为 i 的元素放到第 i 个位置上。
|
||||
|
||||
以 (2, 3, 1, 0, 2, 5) 为例:
|
||||
|
||||
```text-html-basic
|
||||
position-0 : (2,3,1,0,2,5) // 2 <-> 1
|
||||
(1,3,2,0,2,5) // 1 <-> 3
|
||||
(3,1,2,0,2,5) // 3 <-> 0
|
||||
(0,1,2,3,2,5) // already in position
|
||||
position-1 : (0,1,2,3,2,5) // already in position
|
||||
position-2 : (0,1,2,3,2,5) // already in position
|
||||
position-3 : (0,1,2,3,2,5) // already in position
|
||||
position-4 : (0,1,2,3,2,5) // nums[i] == nums[nums[i]], exit
|
||||
```
|
||||
|
||||
遍历到位置 4 时,该位置上的数为 2,但是第 2 个位置上已经有一个 2 的值了,因此可以知道 2 重复。
|
||||
|
||||
```java
|
||||
public boolean duplicate(int[] nums, int length, int[] duplication) {
|
||||
if (nums == null || length <= 0)
|
||||
return false;
|
||||
for (int i = 0; i < length; i++) {
|
||||
while (nums[i] != i) {
|
||||
if (nums[i] == nums[nums[i]]) {
|
||||
duplication[0] = nums[i];
|
||||
return true;
|
||||
}
|
||||
swap(nums, i, nums[i]);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void swap(int[] nums, int i, int j) {
|
||||
int t = nums[i]; nums[i] = nums[j]; nums[j] = t;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
# 参考文献
|
||||
|
||||
- 何海涛. 剑指 Offer[M]. 电子工业出版社, 2012.
|
Loading…
x
Reference in New Issue
Block a user