欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

刷题 9/14

程序员文章站 2022-04-25 10:40:59
...

新浪笔试

  • 如何删除一个非空子目录/tmp:rm -rf /tmp
  • 栈的出栈,入栈序列
  • 2道智力题:青蛙爬井,买房子
  • 计算机网络的302:临时重定向
  • TCP编程中,程序员要做的的事:确定数据格式
  • ping程序使用的协议:ICMP
  • CPU速度级别:在内存中拷贝1GB的文件大概1秒,不知道题意有没有理解错
    刷题 9/14
    cron中的内存常驻程序daemon的作用:管理系统日常任务调度
    代码题:变态青蛙跳
    青蛙一次可以跳1,2,。。。n级台阶,问跳上n级台阶的跳法
    动态规划
    f(n)=2*f(n-1)
    反正就是先跳上1级,后面的有多少种,在跳上2级,后面有多少种
    问答题:
  • TCP三次握手过程
  • get和post的区别
  • session和cookie的区别
  • 地址栏输入url后面的流程
  • B类地址,C类地址的个数
  • 设计一个日变化5000w的系统,总共有五亿用户

电话号码的字母组合

链接:题目链接

题目描述

给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。

给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

刷题 9/14

示例:

输入:“23”
输出:[“ad”, “ae”, “af”, “bd”, “be”, “bf”, “cd”, “ce”, “cf”].

解题思路—递归回溯,或者用队列

看到求组合数,就想到用递归+回溯,当时网易有道的编程题第一题也是这种思想的题目

代码实现
	def get_count(digits):
        if not digits: return []

        phone = {'2':['a','b','c'],
                 '3':['d','e','f'],
                 '4':['g','h','i'],
                 '5':['j','k','l'],
                 '6':['m','n','o'],
                 '7':['p','q','r','s'],
                 '8':['t','u','v'],
                 '9':['w','x','y','z']}
        res = []
        def backtrack(conbination,nextdigit):
            if len(nextdigit) == 0:
                res.append(conbination)
            else:
                for c in phone[nextdigit[0]]:
                    backtrack(conbination+c,nextdigit[1:])
        backtrack("",digits)
        return res
队列实现—这种实现比较巧妙,借鉴 大佬解法
class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        if not digits:
            return []
        # queue要先给一个空串,才能进入循环
        queue = [""]
        phone = ['abc','def','ghi','jkl','mno','pqrs','tuv','wxyz']
        for digit in digits:
            for _ in range(len(queue)):
                tmp = queue.pop(0)
                for c in phone[int(digit)-50]:
                    queue.append(tmp+c)
        return queue

四数之和

链接:题目链接

题目描述

给定一个包含 n 个整数的数组 nums 和一个目标值 target,判断 nums 中是否存在四个元素 a,b,c 和 d ,使得 a + b + c + d 的值与 target 相等?找出所有满足条件且不重复的四元组。

注意:答案中不可以包含重复的四元组。

示例:

给定数组 nums = [1, 0, -1, 0, -2, 2],和 target = 0。

满足要求的四元组集合为:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]

解题思路—双指针

和之前的三数之和的思想类似,这里固定两个数字即可
设定四个指针p,k,i,j

代码实现
class Solution:
    def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
        nums.sort()
        n = len(nums)
        res = []
        p = 0 # p, k, i, j
        while p < n - 3:  # 文中提到的条件1和条件2,可以直接跳过
            if nums[p] + 3 * nums[p + 1] > target: break  
            if nums[p] + 3 * nums[-1] < target:
            	# 这里是因为如果p指针指向的和p+1指向的值相同,跳过即可           
                while p < n - 4 and nums[p] == nums[p + 1]: p += 1
                # 最后因为这个p数值肯定不满足和为target的,所以p指向p+1处即可
                p += 1
                continue
            k = p + 1
            while k < n - 2:   # k 和 p 的判断是一样的
                if nums[p] + nums[k] + 2 * nums[k + 1] > target: break
                if nums[p] + nums[k] + 2 * nums[-1] < target: 
                	# 这个和p的判断类似的
                    while k < n - 3 and nums[k] == nums[k + 1]:
                        k += 1
                    k += 1
                    continue
                i = k + 1
                j = n - 1
                new_target = target - nums[p] - nums[k]
                while i < j:
                	# 这个和三数之和的步骤一样了
                    if nums[i] + nums[j] > new_target: j -= 1
                    elif nums[i] + nums[j] < new_target: i += 1
                    else:
                        res.append([nums[p],nums[k],nums[i],nums[j]])
                        i += 1
                        j -= 1
                        while i < j and nums[i] == nums[i - 1]: i += 1 # 避免结果重复
                        while i < j and nums[j] == nums[j + 1]: j -= 1 # 避免结果重复
                # 这边就是单纯的去重复的元素了
                while k < n - 3 and nums[k] == nums[k + 1]: k += 1
                k += 1
            # 这边也是单纯的去重复元素了
            while p < n - 4 and nums[p] == nums[p + 1]: p += 1
            p += 1
        return res

删除链表的倒数第n个节点

链接:题目链接

题目描述

给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.
说明:

给定的 n 保证是有效的。

进阶:
你能尝试使用一趟扫描实现吗?

解题思路—快慢指针,一次扫描

这题和剑指offer的一题有点像,那题也是快慢指针的思想
总之要先建立一个值不存在的头节点的头,这样能避免删除头节点的这种特殊情况

代码实现
class Solution:
    def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
        dum = ListNode(0)
        dum.next = head
        slow = dum
        fast = head
        for _ in range(n):
            fast = fast.next
        while fast:
            slow = slow.next
            fast = fast.next
        slow.next = slow.next.next
        return dum.next
    

二叉树的中序遍历

链接:题目链接

题目描述

给定一个二叉树,返回它的中序 遍历。

示例:

输入: [1,null,2,3]
1

2
/
3

输出: [1,3,2]
进阶: 递归算法很简单,你可以通过迭代算法完成吗?

解题思路—递归,或者用栈实现迭代,迭代参考:大佬解法

其实递归没什么好说的,比较简单,数据结构都有上,但是迭代实现的话,前中后序遍历的代码会很不一致,这里大佬的解法就不一样了,前中后序的迭代解法代码几乎一样,收下我的膝盖

代码实现,两种,依次为大佬解法和递归解法
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        white, black = 0,1
        stack = [(white,root)]
        res = []
        while stack:
            color,node = stack.pop()
            if node is None:
                continue
            if color == white:
                stack.append((white,node.right))
                stack.append((black,node))
                stack.append((white,node.left))
            else:
                res.append(node.val)
        return res

        # res = []
        # def dfs(root):
        #     if not root:
        #         return 
        #     dfs(root.left)
        #     res.append(root.val)
        #     dfs(root.right)
        # dfs(root)
        # return res