云栖大会限时抢答赛

P1: 和至少为 K 的最短子数组

Leetcode 862
原题一点没改。

P2: 滑动拼图

Leetcode 773
2 × 3 2\times3 2×3改成了 3 × 3 3\times3 3×3
原本可以直接DFS或者A-start搜索,但是,现在会T,终止状态也不好用了。
用优先队列去维护, 计算和最终状态的差值,相同step的情况下, 优先选择差距小的。
可以在优化一些, 排除一些。

import heapq
import collections
class Solution:
    """
    @param init_state: the initial state of chessboard
    @param final_state: the final state of chessboard
    @return: return an integer, denote the number of minimum moving
    """
    def minMoveStep(self, board, target):
        R, C = len(board), len(board[0])
        P = [1] * (R * C)
        for i in range(1, R*C):
            P[i] = 10 * P[i-1]
        f = lambda A: sum(A[i][j] * P[i*C + j] for i in range(R) for j in range(C))
        rs, cs = -1, -1
        for i in range(R):
            for j in range(C):
                if board[i][j] == 0:
                    rs, cs = i, j
        def trans(r, c, state, nr, nc):

            k0 = r * C + c
            k1 = nr * C + nc
            digit = (state // P[k1])% 10
            return state - digit * P[k1] + digit * P[k0]
        

        s_state = f(board)
        f_state = f(target)
        dist_to_f_state = lambda x: abs(x - f_state)
        d = collections.defaultdict(int)
        d[s_state] = 0
        Q = [(0, dist_to_f_state(s_state), rs, cs, s_state)]
        while Q and f_state not in d:
            _, _, r, c, state = heapq.heappop(Q)
            for dx, dy in [[1,0], [-1, 0], [0,1], [0, -1]]:
                nr, nc = r + dx, c + dy
                if 0<= nr < R and 0 <= nc < C:
                    nstate = trans(r, c, state, nr, nc)
                    if nstate not in d or d[nstate] > d[state] + 1:
                        d[nstate] = d[state] + 1
                        heapq.heappush(Q, (d[nstate], dist_to_f_state(nstate),nr, nc, nstate))
        return -1 if f_state not in d else d[f_state]

P3. 地图跳跃

题目
在正方形的地图上, 从左上角(0, 0)跳到(n-1, n-1)的所需要的d的最小值。
对于d的定义是: 如果相邻两个格子之间的绝对值差值小于等于d,那么他们可以跳来跳去。
n ≤ 1000 n\le1000 n1000, 0 ≤ a r r [ i ] ≤ 1 0 5 0\le arr[i]\le 10^5 0arr[i]105

  1. d具有单调性, 如果x满足,那么大于x的点也满足。 而且我们知道答案在 [ 0 , 1 0 5 ] [0, 10^5] [0,105]中。
  2. 二分+验证。
class Solution:
    def mapJump(self, A):
        n = len(A)
        inf = 10 ** 5
        def canReach(target):
            f = lambda x: x[0] * n + x[1]
            vis = {f([0, 0])}
            Q = [[0,0]]
            while Q:
                x, y = Q[0]
                del Q[0]
                for dx, dy in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
                    nx, ny = x + dx, y + dy
                    if 0 <= nx < n and 0 <= ny < n and f([nx, ny]) not in vis and abs(A[x][y] - A[nx][ny]) <= target:
                        Q.append([nx, ny])
                        vis.add(f([nx, ny]))
            return f([n-1, n-1]) in vis
        
        L, R = 0, inf
        while L < R:
            mid = (L + R) >> 1
            if canReach(mid):
                L, R = L, mid
            else:
                L, R = mid+1, R
        return R
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值