精选Top面试题(3)

204计算质数(python)
#埃拉托斯特尼筛法

class Solution(object):
    def countPrimes(self, n):
        if n < 2:
            return 0
        isPrime = [1] * n
        isPrime[0] = isPrime[1] = 0   # 01不是质数,先排除掉

        # 埃式筛,把不大于根号n的所有质数的倍数剔除
        for i in range(2, int(n ** 0.5) + 1):
            if isPrime[i]:
                isPrime[i * i:n:i] = [0] * ((n - 1 - i * i) // i + 1)

        return sum(isPrime)

207-课程表(python)
#深度优先

class Solution(object):
    def canFinish(self,numCourses,prerequisites):
        from collections import defaultdict
        graph = defaultdict(list)
        # 记录
        visited = set()
        # 建图
        for x, y in prerequisites:
            graph[y].append(x)

        # 深度遍历
        def dfs(i, being_visited):
            if i in being_visited: return False
            if i in visited: return True
            visited.add(i)
            being_visited.add(i)
            for j in graph[i]:
                if not dfs(j, being_visited): return False
            being_visited.remove(i)
            return True
        # 检测每门功课起始是否存在环
        for i in range(numCourses):
            # 已经访问过
            if i in visited: continue
            if not dfs(i, set()): return False
        return True

208-前缀树(python)
#字典按字母迭代

class Trie:
    def __init__(self):
        self.lookup = {}     
    def insert(self, word: str) -> None:
        tree = self.lookup
        for a in word:
            if a not in tree:
                tree[a] = {}
            tree = tree[a]
        # 单词结束标志
        tree["#"] = "#"       
    def search(self, word: str) -> bool:
        tree = self.lookup
        for a in word:
            if a not in tree:
                return False
            tree = tree[a]
        if "#" in tree:
            return True
        return False     
    def startsWith(self, prefix: str) -> bool:
        tree = self.lookup
        for a in prefix:
            if a not in tree:
                return False
            tree = tree[a]
        return True

210-课程表2(python)

class Solution:
    def findOrder(self, numCourses: int, prerequisites: List[List[int]]) -> List[int]:
        from collections import defaultdict
        graph = defaultdict(list)
        for x, y in prerequisites:
            graph[y].append(x)
        res = []
        visited = set()

        def dfs(i, being_visited):
            if i in being_visited:
                return False
            if i in visited:
                return True
            visited.add(i)
            being_visited.add(i)
            for j in graph[i]:
                if not dfs(j, being_visited):
                    return False
            being_visited.remove(i)
            res.append(i)
            return True
        for i in range(numCourses):
            if not dfs(i, set()):
                return []
        return res[::-1]

130-被围绕的区域(python)
#分治

class Solution(object):
    def getSkyline(self, buildings):
        if not buildings: return []
        if len(buildings) == 1:
            return [[buildings[0][0], buildings[0][2]], [buildings[0][1], 0]]
        mid = len(buildings) // 2
        left = self.getSkyline(buildings[:mid])
        right = self.getSkyline(buildings[mid:])
        return self.merge(left, right)

    # 两个合并
    def merge(self, left, right):
        # 记录目前左右建筑物的高度
        lheight = rheight = 0
        # 位置
        l = r = 0
        # 输出结果
        res = []
        while l < len(left) and r < len(right):
            if left[l][0] < right[r][0]:
                # current point
                cp = [left[l][0], max(left[l][1], rheight)]
                lheight = left[l][1]
                l += 1
            elif left[l][0] > right[r][0]:
                cp = [right[r][0], max(right[r][1], lheight)]
                rheight = right[r][1]
                r += 1
            # 相等情况
            else:
                cp = [left[l][0], max(left[l][1], right[r][1])]
                lheight = left[l][1]
                rheight = right[r][1]
                l += 1
                r += 1
            # 和前面高度比较,不一样才加入
            if len(res) == 0 or res[-1][1] != cp[1]:
                res.append(cp)
        # 剩余部分添加进去
        res.extend(left[l:] or right[r:])
        return res

227-基本计算器2(python)

class Solution(object):
    def calculate(self,s):
    	num=0
    	stack=[]
    	op='+'
    	for i,c in enumerate(s):
    		if c.isnumeric():
    			num=num*10+int(c)
    		if c in '+-*/' or i==len(s)-1:
    			if op='+':
    				stack.append(num)
    			if op='-':
    				stack.append(-num)
    			if op='*':
    				stack.append(stack.pop()*num)
    			if op='/':
    				stack.append(stack.pop()/num)
    			op=c
    			num=0
    	return sum(stack)

242-有效的字母异位词(python)
#排序

class Solution:
    def isAnagram(self, s: str, t: str) -> bool:
        return sorted(s) == sorted(t)

268-缺失数字(python)

class Solution(object):
    def missingNumber(self,nums):
    	nums_set=set(nums)
    	n=len(nums)+1
    	for number in range(n):
    		if number not in nums_set:
    			return number
    	return  -1

287-寻找重复数(python)
#排序后比较

class Solution(object):
    def findDuplicate(self, nums):
        nums.sort()
        for i in range(1, len(nums)):
            if nums[i] == nums[i-1]:
                return nums[i]

289-生命游戏(python)
#统计每个周围有多少活细胞数

class Solution:
    def gameOfLife(self, board: List[List[int]]) -> None:
        if not board or not board[0]:
            return
        
        m, n = len(board), len(board[0])
        for i in range(m):
            for j in range(n):
                cnt = self.count_alive(board, i, j)
                if board[i][j] and cnt in [2, 3]:
                    board[i][j] = 3
                if not board[i][j] and cnt == 3:
                    board[i][j] = 2
        
        for i in range(m):
            for j in range(n):
                board[i][j] >>= 1
    
    def count_alive(self, board, i, j):
        m, n = len(board), len(board[0])
        cnt = 0
        directions = [(0, 1), (0, -1), (-1, 0), (1, 0),
                      (1, 1), (1, -1), (-1, 1), (-1, -1)]
        
        for dx, dy in directions:
            x, y = i + dx, j + dy
            if x < 0 or y < 0 or x == m or y == n:
                continue
            cnt += board[x][y] & 1
        
        return cnt

295-数据流中的中位数(python)
#用数组存,排序找中位数

class MedianFinder:
    def __init__(self):
        self.store = []

    def addNum(self, num: int) -> None:
        self.store.append(num)

    def findMedian(self) -> float:
        self.store.sort()
        n = len(self.store)
        if n & 1 == 1: # n 是奇数
            return self.store[n // 2]
        else:
            return (self.store[n // 2 - 1] + self.store[n // 2]) / 2

300-最长上升子序列(python)
#动态规划

class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        if not nums:
            return 0
        dp=[1]*len(nums)
        for i in range(len(nums)):
            for j in range(i):
                if nums[j]<nums[i]:
                    dp[i]=max(dp[i],dp[j]+1)
        return max(dp)

315-计算右侧小于当前元素个数(python)
#输入数组反过来插入一个有序数组(降序)中,插入的位置就是在原数组中位于它右侧的元素的个数

class Solution(object):
    def countSmaller(self, nums):
        sortns = []
        res = []
        for n in reversed(nums):
            idx = bisect.bisect_left(sortns, n)
            res.append(idx)
            sortns.insert(idx,n)
        return res[::-1]

324-摆动排序(python)
#利用排序 进行插入

class Solution:
    def wiggleSort(self, nums: List[int]) -> None:
        nums.sort(reverse=True)
        mid=len(nums)//2
        nums[1::2],nums[0::2]=nums[:mid],nums[mid:]

326-3的幂(python)

class Solution(object):
    def isPowerOfTree(self,n):
    	if n<1:return False
    	while n%3==0:
    		n/=3
    	return n==1

328-奇偶链表(python)

class Solution(object):
    def oddEvenlist(self,head):
    	if not head:return head
    	p=head
    	t=q=p.next
    	while q and q.next:
    		p.next=q.next
    		q.next=q.next.next
    		p=p.next
    		q=q.next
    	p.next=t
    	return head

329-矩阵中的最长递增路径(python)

class Solution(object):
    def longestIncreasingPath(self, matrix):
        if not matrix:
            return 0
        len_r=len(matrix)
        len_c=len(matrix[0])
        dis=[[1,0],[-1,0],[0,1],[0,-1]]
        ans=0
        mon=[[0]*len_c for _ in range(len_r)]
        for nr in range(len_r):
            for nc in range(len_c):
                ans=max(ans,self.dfs(matrix,nr,nc,dis,mon))
        return ans
    def dfs(self,matrix,r,c,dis,mon):
        if mon[r][c]!=0:
            return mon[r][c]
        longest=1
        for d in dis:
            x=r+d[0]
            y=c+d[1]
            if x>=0 and x<len(matrix) and y>=0 and y<len(matrix[0]) and matrix[r][c]<matrix[x][y]:
                longest=max(longest,1+self.dfs(matrix,x,y,dis,mon))
        mon[r][c]=longest
        return mon[r][c]

334-递增三元子序列(python)

class Solution(object):
    def iscreasingTriplet(self,nums):
    	if len(nums)<3:return False
    	win=[nums[0]]
		for num in nums:
			if num>win[-1]:
				win.append(num)
				if len(win)>=3:
					return True
			else:
				i=len(win)-1
				if i>0 and win[i-1]>=num:
					i-=1
				win[i]=num
		return False

350-两数组的交集2(python)

class Solution(object):
    def intersect(self,nums1,nums2):
    	if len(nums1)>len(nums2):
    		return self.intersect(nums2,nums1)
    	hash={}
    	for num in nums1:
    		hash[nums]=hash.get(num,0)+1
    	res=[]
    	for num in nums2:
    		if num in hash and hash[num]>0:
    			res.append(num)
    			hash[num]-=1
    	return res

371-两整数之和(python)

class Solution(object):
    def getSum(self, a, b):
        c = []
        c.append(a)
        c.append(b)
        return sum(c)

378-有序矩阵中第K小的元素(python)
#左上角最小 右下角最大 二分法查找

class Solution(object):
    def kthSmallest(self, matrix, k):
        # 计算小于等于目标值的元素个数,根据递增规则,从右上角开始查找
        def count_num(m, target):
            i = 0
            j = len(m) - 1
            ans = 0
            while i < len(m) and j >= 0:
                if m[i][j] <= target:
                    ans += j + 1
                    i += 1
                else:
                    j -= 1
            return ans
        
        #  思路:左上角元素最小,右下角元素最大,计算小于等于中间值的元素个数
        left = matrix[0][0]
        right = matrix[-1][-1]
        # 二分法查找
        while left < right:
            mid = (left + right) //2
            # print(' mid = ', mid)
            count = count_num(matrix, mid)
            # print('count = ', count)
            if count < k:
                left = mid + 1
            else:
                right = mid
        return left

380-常数时间插入、删除和获取随机元素(python)

class RandomizedSet:
    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.dict = {}
        self.list = []        
    def insert(self, val: int) -> bool:
        """
        Inserts a value to the set. Returns true if the set did not already contain the specified element.
        """
        if val in self.dict:
            return False
        self.dict[val] = len(self.list)
        self.list.append(val)
        return True       

    def remove(self, val: int) -> bool:
        """
        Removes a value from the set. Returns true if the set contained the specified element.
        """
        if val in self.dict:
            # move the last element to the place idx of the element to delete
            last_element, idx = self.list[-1], self.dict[val]
            self.list[idx], self.dict[last_element] = last_element, idx
            # delete the last element
            self.list.pop()
            del self.dict[val]
            return True
        return False

    def getRandom(self) -> int:
        """
        Get a random element from the set.
        """
        return self.list[random.randint(0, len(self.list) - 1)] 

380-常数时间插入、删除和获取随机元素(python)
#哈希

class RandomizedSet:

    def __init__(self):
        """
        Initialize your data structure here.
        """
        self.dict = {}
        self.list = []        
    def insert(self, val: int) -> bool:
        """
        Inserts a value to the set. Returns true if the set did not already contain the specified element.
        """
        if val in self.dict:
            return False
        self.dict[val] = len(self.list)
        self.list.append(val)
        return True
        

    def remove(self, val: int) -> bool:
        """
        Removes a value from the set. Returns true if the set contained the specified element.
        """
        if val in self.dict:
            # move the last element to the place idx of the element to delete
            last_element, idx = self.list[-1], self.dict[val]
            self.list[idx], self.dict[last_element] = last_element, idx
            # delete the last element
            self.list.pop()
            del self.dict[val]
            return True
        return False

    def getRandom(self) -> int:
        """
        Get a random element from the set.
        """
        return self.list[random.randint(0, len(self.list) - 1)]

384-打乱数组(python)

class Solution(object):

    def __init__(self, nums):
        self.nums = nums

    def reset(self):
        return self.nums

    def shuffle(self):
        array = copy.copy(self.nums)
        for i in range(len(array)):
            random_num = random.randint(i,len(array)-1)
            array[i], array[random_num] = array[random_num], array[i]
        return array

387-字符串中第一个唯一字符(python)

class Solution(object):
    def firstUniqchar(self,s):
    	dicts={}
    	for i in s:
    		dicts[i]=dicts.get(i,0)+1
    	for i in range(len(s)):
    		if dicts[s[i]]==1:
    			return i
    	return -1

395-至少有K个重复字符的最长子串(python)

class Solution(object):
    def longestSubstring(self, s, k):
        def find(s, k, left, right):
            if left > right:
                return 0
            
            # 用字典存储所有字符出现的情况
            hash_map = dict()
            for i in range(left, right + 1):
                c = s[i]
                if hash_map.get(c, None) == None:
                    hash_map[c] = []
                hash_map[c].append(i)#这是一数组
                
            for key in hash_map.keys():
                # 某个字符出现的次数
                counter = len(hash_map[key])
                # 如果字符出现次数 < k,那么该字符不可能出现在最终要求的子串中,在该字符的位置对原字符串进行截断
                if counter > 0 and counter < k:
                    # 该字符首次出现的位置
                    pos = hash_map[key][0]
                    # 根据该字符的位置对字符串进行截断,判断左右两个截断的字字符哪个更长
                    return max(find(s, k, left, pos - 1), find(s, k, pos + 1, right))
            
            return right - left + 1
        
        return find(s, k, 0, len(s) - 1)

412-FizzBuzz(python)

class Solution(object):
    def fizzBuzz(self,n):
    	ans=[]
    	for i in range(1,n+1):
    		div_by_3=(i%3==0)
    		div_by_5=(i%5==0)
    		if div_by_3 and div_by_5:
    			ans.append("FizzBUzz")
    		elif div_by_3:
    			ans.append("Fizz")
    		elif div_by_5:
    			ans.append("Buzz")
    		else:
    			ans.append(i)
    	return ans

454-四数相加2(python)
#key-value

class Solution(object):
    def fourSumCount(self,A,B,C,D):
    	lookup=collections.defaultdict(int)
    	res=0
    	for a in A:
    		for b in B:
    			lookup[a+b]+=1
    	for c in C:
    		for d in D:
    			res+=lookup[-(c+d)]
    	return res

你可能感兴趣的:(精选Top面试题(3))