CS-Notes/notes/面试总结.md
孙海洲 3d344ea1ce
Create 面试总结.md
把自己平时面试的笔试算法题目做一个整理记录,方便以后查阅。
2018-09-19 10:01:05 +08:00

3.9 KiB
Raw Blame History

1. 字符串组合

题目描述

给定三种类型的小球P、Q、R每种小球的数量分别为np、nq、nr个。现在想讲这些小球排成一条直线但是不允许相同类型的小球相邻问有多少种排序方法。 如若np=2nq=1,nr=1则共有6种排列方式PQRP、QPRP、PRQP、PRPQ、RPQP以及PQPR。如果无法组合出合适的结果则输出0.

输入

一行以空格相隔的三个数分别表示为np、nq、nr。

输出

排列方法的数量。

样例输入

2 1 1

样例输出

6

解题思路

本题采用一种比较直接的方式进行解题,分为如下步骤:

  1. 求解给定P、Q、R个数的时候的全排列提供Python提供的itertools.permutations来实现,此时肯定有很多重复。
  2. 去掉重复的情况,通过Python提供的set来实现。
  3. 通过遍历找出相邻元素重复的串。
  4. 求两个集合的差集,即为答案。
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

单例模式

3. 数组中重复的数字

NowCoder

题目描述

在一个长度为 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) 为例:

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 重复。

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.