sc onsite

P1 找Amicable Number Pairs 就是 数A 的所有因数(包括1,不包括A) 之和 等于 B。B的所有因数之和又刚好为A。 且 A != B. 求[1, N] 中所有符合条件的pair

思路:先用一个array把每个数的因数和全部存起来。然后再遍历这个array找pair就行了。i = record[record[i]]就可以了。

class Solution(object):
    def amiPair(self, n):
        record = [0]*(n+1)
        res = []
        # first we record sum
        for i in range(1, n):
            record[i] = sum(e for e in range(1,i//2+1) if i%e==0)
        # then we find the pair
        for i in range(1, n):
            if i<record[i] and record[i]<n and i == record[record[i]]:
                res.append([i, record[i]])
        return res

n = 1000
so = Solution()
a = so.amiPair(n)
print a

P2 coding题目是一个矩阵里某些位置有墙,给一个出发点及目的地,求最短距离。 如果只需能否通过,那就DFS。要计算距离,那就BFS。 follwup是现在墙可以打破,没打破一个cost为1,求cost最小的路线。 需要把每个node再加个成员变量cost,在终点取最小的cost,注意中途遇到访问过而且cost小的才不加。一定要画画图。

class Solution(object):
    def findPath(self, matrix, start, end):
        """
        :type matrix: List[List[int]]
        :type start: List[int]
        :type end: List[int]
        :rtype: Bool 
        """
        if not matrix or not matrix[0]:
            return False

        s = [start]
        visited = set()

        while s:
            tmp = s.pop()
            for dp in [(1, 0), (-1, 0), (0, 1), (0, -1)]:
                i, j = tmp[0]+dp[0],tmp[1]+dp[1]
                print i,j
                if [i, j] == end:
                    return True
                if 0<=i<len(matrix) and 0<=j<len(matrix[0]) and (i,j) not in visited and matrix[i][j]!=1:
                    visited.add((i,j))
                    s.append([i,j])
        return False

so = Solution()
matrix=[[0,1],[1,0]]
s, e = [0,0], [1,1]
a = so.findPath(matrix, s, e)
print a

P3 有一堆数, 比如{2,3,5,8}. 每次带2个过去, 比如我选了3和5, cost是最大的那个值. 一旦过去, 还要带回来一个数. 比如带回3, 花销是3. 所以这一趟把5运了过去, 总花销是3+5. 求找出最小的花销运过去所有数字.

思路:天下武功,唯暴力不破。直接暴力dfs吧。优化的解法如下: http://blog.csdn.net/morewindows/article/details/7481851 不过提供面经这个哥们暴力dfs也拿到offer了。所以。还是装作不会最优解吧。科科

class Solution(object):
    def lowCost(self, nums):
        self.res = float('inf')
        self.dfs(nums, [],[], 0)
        return self.res

    def dfs(self, nums, end, path, cost):

        if len(nums)==2:
            if cost+max(nums)<self.res:
                self.res = cost+max(nums)

        for i in range(len(nums)-1):
            for j in range(i+1, len(nums)):
                # get 2 num from nums
                next_nums = nums[:]
                next_end = end[:]
                next_cost = cost
                a, b = next_nums[i], next_nums[j]
                next_nums.remove(a)
                next_nums.remove(b)
                next_cost += max(a,b)
                next_end += [a,b]
                # get 1 from end
                c = min(next_end)
                next_cost += c
                next_end.remove(c)
                next_nums.append(c)
                self.dfs(next_nums, next_end, path+[[a,b,c]], next_cost)

nums = [2,3,5,8]
so = Solution()
a = so.lowCost(nums)
print a

p4. 给定数组,只有正数,使用+和*和()。求最大值。 使用DP解决。dp[j] = max(dp[m - 1] + dp[m][j], dp[m - 1] * dp[m][j]);

class Solution(object):
    def findmax(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        self.memo = {}
        res = self.dfs(nums, 0, len(nums)-1)
        return res

    def dfs(self, nums, l, r):

        if (l, r) in self.memo:
            return self.memo[l, r]

        if l == r:
            return nums[l]

        res = 0
        for i in range(l, r):
            left = self.dfs(nums, l, i)
            right = self.dfs(nums, i+1, r)
            tmp = max(left + right, left * right)
            res = max(res, tmp)

        self.memo[(l, r)] = res
        return res


nums = [1,2,3]
so = Solution()
a = so.findmax(nums)
print(a)

P5 3d grid,每个点有高度, 给起点和终点,求一个直升机起点到终点高度和最小的路径,注意一点是直升机只能上升不能下降

思路:这道题用我写的 Dijkstra's Algorithm 就行了。你把高度看成cost。想当与就是求(0,0)到(2,2)的最短路径嘛。这只是最简单的Dijkstra,里面的那个Q可以用ordered dict来实现。或者用hashed Priority Queue来优化。面试的时候我觉得写成这样就差不多可以过了。

class Solution(object):
    def flyChicken(self, m, start, end):
        D = {}
        Q = {}

        Q[start] = 0

        while Q:
            v = self.get_min(Q)
            D[v] = Q[v]
            for dp in [(-1,0), (1,0), (0,1), (0,-1)]:
                i, j = v[0]+dp[0], v[1]+dp[1]
                if 0<=i<len(m) and 0<=j<len(m[0]):
                    dist = Q[v] + m[i][j]
                    if (i, j) in D:
                        if dist<D[(i,j)]:
                            raise ValueError
                    else:
                        if (i,j) not in Q or dist<Q[(i,j)]:
                            Q[(i,j)] = dist
            del Q[v]

        return D[(2,2)]

    def get_min(self, Q):
        m = (None, float('inf'))
        for k in Q:
            if Q[k]<m[1]:
                m = (k, Q[k])
        return m[0]

# example, CLR p.528
Matrix = [[0,1,2],
          [1,2,3],
          [1,1,4]]

so = Solution()
print so.flyChicken(Matrix, (0,0), (2,2))

P6 E.g. storeBadIps(["7.0.0.0/8", "10.3.0.0/16", "6.7.8.134/32"]) In the example "7.0.0.0/8", "7.0.0.0" is ip ranges from 0.0.0.0 to 255.255.255.255, "8" is how many bits from the beginning it needs to match. in this example any "7.x.x.x" would be a bad ip. In the example "10.3.0.0/16", any "10.3.x.x" would be a bad ip. In the example "6.7.8.134/32", only exact match "6.7.8.134" would be a bad ip.

思路:这题没什么好说的呀,就是建立trie嘛,然后新来的ip.就找在不在trie里面。

class Node(object):
    def __init__(self):
        self.children = {}
        self.isEnd = False

class Solution(object):
    def __init__(self, list):
        self.root = Node()
        for ip in list:
            [ip, length] = ip.split('/')
            ip = ip.split('.')
            head = self.root
            for i in range(0, int(length), 8):
                if ip[i//8] not in head.children:
                    head.children[ip[i//8]] = Node()
                head = head.children[ip[i//8]]
            head.isEnd = True

    def badIp(self, ip):
        ip = ip.split('.')
        head = self.root
        for i in range(0, 32, 8):
            if ip[i//8] not in head.children:
                return False
            head = head.children[ip[i//8]]
            if head.isEnd==True:
                return True
        return False

l = ["7.0.0.0/8", "10.3.0.0/16", "6.7.8.134/32"]
so = Solution(l)
ans = so.badIp("6.7.8.x")
print ans

P7. N 个person和N 个bike在一个2维度数组里配对,一个person配对一个bike,要求所有配对的距离加起来和最小,面试官只要求讲思路。并提示greedy算法, 这题目我只给出了bruteforce的枚举法思路,时间复杂度是O(n!),面试官说还有greedy算法可以优化成O(n^2)复杂度,但事后我觉得此题用greedy 算法只能近似求解,面试官给出的解法根本就无法求解全局最优解嘛。 不知道有没有高手可以用O(n^2)解出来,打我的脸。

思路:我觉得其实面试官就想要一个greedy的次优解法。然后我就按照面试官的要求写了一个。

import math
class Solution(object):
    def assignBike(self, p, b):
        ps = set(p)
        bs = set(b)

        dis_list = []
        for i in p:
            for j in b:
                dis = math.sqrt((i[0]-j[0])**2+(i[1]-j[1])**2)
                dis_list.append((dis,i,j))
        dis_list.sort(key=lambda x: x[0])

        cost = 0
        res = []
        while ps and bs:
            [dis, i, j] = dis_list.pop(0)
            if i in ps and j in bs:
                ps.remove(i)
                bs.remove(j)
                cost += dis
                res.append((i,j))
        return cost, res

p = [(1,1), (1,2)]
b = [(2,1), (2,2)]
so = Solution()
ans = so.assignBike(p, b)
print ans

p8 小哥说话挺慢的,先让自我介绍,问了why snapchat, 实习经历里面最exciting的事是啥以及实习过程中有没有不开心的事 题目问了XML parser, LZ不熟悉XML,就改成了HTML Parser, 本质上一样 输入是一个tokenizer对象,可以调用其getNextToken()函数获得下一个token, token结构包括name和tag,name就是具体的文字,tag有open,close,text三种,让把所有的token建成一棵树 比如:

       <html>
            <user>
                <id>aa</id>
                <meta>bb</meta>
            </user>
       </html>

得到的token就是 ("html","open") ("user","open") ("id","open") ("aa","text") ("id","close") ("meta","open") ("bb","text") ("meta","close") ("user","close") ("html","close")

思路:是不是有点过于简单了,简直是放水嘛。还是还是我想错了。

class Node(object):
    def __init__(self):
        self.text = None
        self.children = {}

class Solution(object):
    def xmlParser(self, tokens):
        root = Node()
        s = [root]
        for t in tokens:
            print t
            if t[1]=='open':
                tmp = Node()
                s[-1].children[t[0]] = tmp
                s.append(tmp)
            elif t[1]=='close':
                s.pop()
            elif t[1]=='text':
                s[-1].text = t[0]
        return root

P9 一个2D平面有一堆雷达(雷达有x, y坐标,以及能探测到的范围r半径)然后又一辆小车要从y=0和y=1的区间里面通过并且不能被雷达探测到。让写一个function看小车能不能通过 我用dfs写了一个。判断2D grid能不能从一边到另外一边的。 下次用union find写一下。

class Solution(object):
    def canPass(self, sensor, matrix):
        """
        :type sensor: List[tuple]
        :type matrix: List[List[int]]
        :rtype: Bool
        """

        # process the grid
        for s in sensor:
            x, y, r = s[0], s[1], s[2]
            for i in range(x-r, x+r+1):
                for j in range(y-r, y+r+1):
                    if 0<=i<len(matrix[0]) and 0<=j<len(matrix):
                        dist = ((x-i)**2 + (y-j)**2)**(1.0/2)
                        if dist<=r:
                            matrix[i][j]=1

        # build the start points and end points
        s, end = [], []
        for j in range(len(matrix[0])):
            if matrix[0][j]==0:
                s.append((0,j))
            if matrix[len(matrix)-1][j]==0:
                end.append((len(matrix)-1,j))

        # dfs
        visited = set(s)
        while s:
            tmp = s.pop()
            if tmp in end:
                return True
            for dp in [(-1,0), (1,0), (0,1), (0,-1)]:
                i, j = tmp[0]+dp[0], tmp[1]+dp[1]
                if 0<=i<len(matrix[0]) and 0<=j<len(matrix)\
                and matrix[i][j]==0 and (i,j) not in visited:
                    visited.add((i,j))
                    s.append((i,j))
        return False


matrix = [[0]*4 for _ in range(4)]
sensor = [(1,0,1), (3,3,1)]
so = Solution()
ans = so.canPass(sensor, matrix)
print ans

P10 题目: ternary expression paser (三目运算符), input是一个string,其中 'T' 表示true, 'F' 表示false, 要求返回最后运算的结果。

乍一看题目很直接, bool expression ? first result : second result ,但实际上我们通常都用的都是非常简单的形式,但每一部分都可以无限嵌套。例如: T ? T : F ? T : 1 : 2 : F ? 3 : 4; 原本妹子没让我考虑bool expression部分也嵌套的情况,结果我本着把问题分析清楚的原则,成功把问题弄的复杂了,她后来觉得这可以作为follow up。。。.1point3acres缃� 说了两三个简单的solution,然后举例发现有问题。在妹子的提示下,写出了 “不考虑 bool expression”的情况,但是因为已经说出口了,妹子指出我还需要继续考虑。最终时间不够,没有运行代码。 过后发现,确实应该多在纸上找一下规律,理清逻辑在写解法。string的变式题对我来说比较tricky,完全在脑子里思考容易变成一团浆糊。。。。妹子对我我说,没事她比较看重逻辑。我心里只能说谢谢你的安慰。。T.T

class Solution(object):
    def boolExpression(self, s):
        ops=[]
        nums=[]

        for i in s:
            if i in '0123456789':
                nums.append(i)
                self.applyOp(ops, nums)
            elif i in 'TF':
                nums.append(i)
            elif i in ':?':
                ops.append(i)
        return nums[-1]


    def applyOp(self, ops, nums):
        while len(ops)>1 and ops[-1]==':' and ops[-2]=='?':
            x, y = nums.pop(), nums.pop()
            b = nums.pop()
            res = y if b=='T' else x
            nums.append(res)
            ops.pop()
            ops.pop()



s = 'T?F?1:3:2'
so = Solution()
a = so.boolExpression(s)
print(a)

P10 unique paths I + II

https://leetcode.com/problems/unique-paths/

原题没什么好说的。

class Solution(object):
    def uniquePaths(self, m, n):
        """
        :type m: int
        :type n: int
        :rtype: int
        """
        dp = [[0]*n for _ in range(m)]

        for i in range(m):
            for j in range(n):
                if i==0 or j==0:
                    dp[i][j]=1
                else:
                    dp[i][j] = dp[i-1][j]+dp[i][j-1]

        return dp[-1][-1]

2

class Solution(object):
    def uniquePathsWithObstacles(self, obstacleGrid):
        """
        :type obstacleGrid: List[List[int]]
        :rtype: int
        """
        if not obstacleGrid or not obstacleGrid[0]:return -1
        m, n = len(obstacleGrid), len(obstacleGrid[0])
        dp = [[0]*n for _ in range(m)]

        for i in range(m):
            for j in range(n):
                if obstacleGrid[i][j]==1:
                    dp[i][j]==0
                else:
                    if i==0 and j==0:
                        dp[i][j]=1
                    elif i == 0:
                        dp[i][j] = dp[i][j-1]
                    elif j ==0:
                        dp[i][j] = dp[i-1][j]
                    else:
                        dp[i][j] = dp[i-1][j] + dp[i][j-1]

        return dp[-1][-1]

results matching ""

    No results matching ""