Leetcode经典面试题 -- 第2周

Leetcode经典面试题 – 第2周

题目来源于Leetcode
报了一个百面机器学习面试的课程
每周都有定时打卡的作业
都是常出现于面试中的题
总结在此,时常温习,
刷题小能手们觉得写的不错可以移步个人主页
(ps:最近忙着笔试面试,更新太少)


1.二分(Leetcode 69)

Implement int sqrt(int x).
Compute and return the square root of x, where x is guaranteed to be a non-negative integer.
Since the return type is an integer, the decimal digits are truncated and only the integer part of the result is returned.

实现根号n的函数,保留整数位

Example 1:
Input: 4
Output: 2

Example 2:
Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842…, and since
the decimal part is truncated, 2 is returned.

思路

题目要求二分法,有根区间初始化为(0,n)
根据左右区间的函数乘积小于0
可以不断缩小有根区间到一定的误差值范围

快捷的方法是牛顿迭代法
目标函数是 f ( x ) = x 2 − a f(x)=x^{2}-a f(x)=x2a
利用泰勒公式展开得到公式 x k + 1 = x k − f ( x k ) f ′ ( x k ) {x_{k + 1}} = {x_k} - \frac{{f({x_k})}}{{f'({x_k})}} xk+1=xkf(xk)f(xk)
进一步得到 x k + 1 = x k + a x k 2 x_{k+1} =\frac{x_{k}+\frac{a}{x_{k}}}{2} xk+1=2xk+xka的迭代公式
比二分更容易收敛。

class Solution(object):
	def mySqrt_binary_search(self, x):
        lo = 0
        hi = x
        while lo <= hi:
            mid = lo + (hi - lo) >> 1
            if mid ** 2 <= x < (mid+1) ** 2:
                return mid
            if mid ** 2 > x:
                hi = mid
            else:
                lo = mid + 1
    def mySqrt_newton(self, x):
        """
        :type x: int
        :rtype: int
        """
        y = 1
        while(1):
        	new = ((y)+(x/y))/2
        	if abs(new-y) < 0.0000001:
        		break
        	y = new
        return int(y)

2.分治(Leetcode 241)

Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. The valid operators are +, - and *.
给定了一串数字和运算符,返回所有可能的计算结果

Example 1:
Input: “2-1-1”
Output: [0, 2]
Explanation:
((2-1)-1) = 0
(2-(1-1)) = 2

Example 2:
Input: “23-45”
Output: [-34, -14, -10, -10, 10]
Explanation:
(2*(3-(45))) = -34
((2
3)-(45)) = -14
((2
(3-4))5) = -10
(2
((3-4)5)) = -10
(((2
3)-4)*5) = 10

思路

分治的基本思想:
将一个规模为N的问题分解为K个规模较小的子问题
这些子问题相互独立且与原问题性质相同
求出子问题的解,就可得到原问题的解
具体到这一题:
基本出口:碰到当前操作的数据是数字返回当前数字
基本流程:搜索运算符,左右分治,分别得到左边运算结果和右边运算结果,细分向下搜索到最后一个子问题,完成对应运算即可解决原问题。

class Solution(object):
	def helper(self, a, b, op):
		if op == '+':
			return a + b
		if op == '-':
			return a - b
		if op == '*':
			return a * b


    def diffWaysToCompute(self, input):
        """
        :type input: str
        :rtype: List[int]
        """
        res = []
        if input.isdigit():
        	return [int(input)]
        for i in range(len(input)):
        	cur_op = input[i]
        	if cur_op in'+-*':
        		res1 = self.diffWaysToCompute(input[:i])
        		res2 = self.diffWaysToCompute(input[i+1:])
        		for j in res1:
        			for k in res2:
        				res.append(j, k, cur_op)
        return res
        

2 × 3 − 4 × 5 2\times3-4\times5 2×34×5为例,结合上述完成的代码,整个分治的流程的详细走势,如下图所示:
分治流程图
总的来说,分治就是查找最小的一个子问题,这里最小的一个子问题就是,+/-/*运算,用helper这个函数来完成这些基本运算,不断的循环这个过程,在不断处理这些子问题的同时,原问题也得到解决,注意在编程过程中的list和int类型的相互转化。


3.链表(Leetcode 160)

Write a program to find the node at which the intersection of two singly linked lists begins.
写一个函数返回两个链表的交叉点,交叉点之后的元素都要相等,返回交叉点的值,都是图不方便插入,直接留下传送门

思路

设两个链表长度差为n,让两个指针指向两个链表,若两个链表有交集,长链表的指针到头之后指向短链表,短链表的指针到头后指向长链表,能够实现将长链表提前走过长度差n,这样当两个指针相等时,那个点就是交叉点。

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def getIntersectionNode(self, headA, headB):
    	if headA is None or headB is None:
	    	return None
		pa, pb = headA, headB
	    while headA is not headB:
	    	if pa is None:
	    		pa = headB
	    	else:
	    		pa = pa.next
	    	if pb is None:
	    		pb = headA
	    	else:
	    		pb = pb.next
	    return pa

4.哈希表(Leetcode 1)

Given an array of integers, return indices of the two numbers such that they add up to a specific target.
给定一组数,返回和为指定数的两个数组中的数的索引

思路

遍历数组,对每一个遍历到的数,判断剩下的数中有没有target-current,有的话返回索引即可

class Solution:
    def twoSum(self, nums, target):
        d = {}
        first = -1
        second = -1
        for i in range(len(nums)):
	        r = target - nums[i]
	        if r in d:
	        	first = d[r]
	        	second = i
	        d[nums[i]] = i
	      return first, second

5.字符串(Leetcode 242)

Given two strings s and t , write a function to determine if t is an anagram of s.
给定两个字符串s和t,判断他们是不是相同字母的不同的组合

思路

1.利用字典统计出现的字母及数量,判断两个字符对应的字典是否相等即可
2.直接排序,看是否相等即可

# 第1种方法:字典
class Solution(object):
    def isAnagram(self, s, t):
        d1, d2 = {}, {}
        for i in s:
            d1[i] = d1.get(i, 0) + 1
        for i in t:
            d2[i] = d2.get(i, 0) + 1
        return d1 == d2
# 第2种方法:排序
class Solution(object):
    def isAnagram(self, s, t):
        return sorted(s) == sorted(t)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值