面试算法题

1. 加油站(Leetcode 134)

题目:
在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。
解答:

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {
        int n = gas.length;
        for (int start = 0; start < n; ) {
            if (gas[start] < cost[start]) {
                start ++;
            }
            else {
                int cur = gas[start] - cost[start];
                int idx = start + 1;
                while (idx % n != start) {
                    cur += gas[idx % n] - cost[idx % n];
                    if (cur < 0) break;
                    idx ++;
                }
                if (idx % n == start) return start;
                else start = idx;
            }
        }
        return -1;
    }
}
import numpy as np


class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        gas_len = len(gas)
        spare = 0
        minSpare = np.iinfo(np.int16).max
        minIndex = 0

        for i in range(gas_len):
            spare += gas[i] - cost[i]
            if spare < minSpare:
                minSpare = spare
                minIndex = i

        if spare < 0:
            return -1
        
        return (minIndex + 1) % gas_len

 
 

2. 整数划分

题目:
将整数n分成k份,且每份不能为空,任意两个方案不能相同(不考虑顺序)。
例如:n=7,k=3,下面三种分法被认为是相同的。
1,1,5;
1,5,1;
5,1,1;
问有多少种不同的分法。
输入:n,k ( 6 < n ≤ 200,2 ≤ k ≤ 6 )
输出:一个整数,即不同的分法。
解答:

def divide(n, k):
    if n < k:
        return 0
    if n == k or k == 1:
        return 1
    return divide(n - 1, k - 1) + divide(n - k, k)

 
 

3. 区间求和系列问题

https://leetcode-cn.com/problems/corporate-flight-bookings/solution/gong-shui-san-xie-yi-ti-shuang-jie-chai-fm1ef/

 
 

4. 每日温度

题目:
请根据每日 气温 列表 temperatures ,请计算在每一天需要等几天才会有更高的温度。如果气温在这之后都不会升高,请在该位置用 0 来代替。

示例 1:

  • 输入: temperatures = [73,74,75,71,69,72,76,73]
  • 输出: [1,1,4,2,1,1,0,0]

解答:
利用单调栈的思想,但是需要注意的是,这里的单调栈存的都是下标,而非数值,只是通过数值来确定直接入栈还是栈内元素先出栈,当前元素再入栈。所以单调栈并不一定是指所存的元素是单调的,也可能是该元素对应的某列值是单调的,就像本题所存的下标,但单调的是下标所指的元素。

注:单调栈分为递增栈和递减栈,递增栈是指从栈顶到栈底是递增的,递减栈是从栈顶到栈底是递减的。

class Solution:
    def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
        n = len(temperatures)
        res = [0] * n
        stack = []
        for i in range(n):
            while stack and temperatures[i] > temperatures[stack[-1]]:
                t = stack[-1]
                res[t] = i - t
                stack.pop()
            stack.append(i)
        return res

 
 

5. 拔萝卜

题目:
现在有一个 n ∗ m n * m nm的格子,第 i i i行第 j j j列的格子有 a [ i ] [ j ] a[i][j] a[i][j]个胡萝卜。
现在米兔要从左上角的格子走到右下角的格子,来收集这些胡萝卜。并且每次只能向右或者向下走。
请计算米兔能够收集到的最大胡萝卜数量。

解答:
注:这是一道非常经典的动态规划入门题目,为了缩小内存占用,要在原数组上进行修改。

class Solution:
    def maxPathSum(self , a ):
        n, m = len(a), len(a[0])
        for i in range(1, n):
            a[i][0] += a[i - 1][0]
        for j in range(1, m):
            a[0][j] += a[0][j - 1]
        for i in range(1, n):
            for j in range(1, m):
                a[i][j] += max(a[i - 1][j], a[i][j - 1])
        return a[n - 1][m - 1]

 
 

6. 最长回文子串

 
 

7. 单调栈系列问题

https://leetcode-cn.com/problems/largest-rectangle-in-histogram/solution/bao-li-jie-fa-zhan-by-liweiwei1419/

 
 

8. 疯狂队列

题目:
给一个数组,求它的任意排列,使得排列后的数组相邻元素的差值绝对值(疯狂值)之和最大
例:5 10 25 40 25
最优的排列是25-10-40-5-25,此时差值绝对值之和为100
解答:

  1. 先将原数组进行升序排序
  2. 新建一个双端队列;
  3. 每次在队列的两端加入当前的最大值与最小值;
  4. 如果数组恰好被取完,则循环结束;如果还剩一个,根据疯狂值大小判断放在哪一边
from collections import deque


def f(nums):
    n = len(nums)
    if n == 1:
        return 0
    nums.sort()
    res = deque([nums[0], nums[-1]])
    ans = abs(nums[-1] - nums[0])
    left, right = 1, n - 2
    smaller, larger = 0, -1
    while left < right:
        ans += abs(nums[left] - res[larger]) + abs(nums[right] - res[smaller])
        res.appendleft(nums[left])
        res.append(nums[right])
        left += 1
        right -= 1
    if left == right:
    	a = abs(nums[left] - res[0])
    	b = abs(nums[right] - res[-1])
    	if a > b:
    		ans += a
    		res.appendleft(nums[left])
    	else:
    		ans += b
    		res.append(nums[right])
    return ans

你可能感兴趣的:(面试知识,数据结构与算法,数据结构,算法,面试)