二进制链表转整数
代码:
class Solution {
public:
int getDecimalValue(ListNode* head) {
int ans =0 ;
while(head!=NULL){
ans = ans * 2 + head->val;
head = head->next;
}
return ans;
}
};
class Solution:
def getDecimalValue(self, head):
ans = 0
while head !=None:
ans = ans* 2 + head.val
head = head.next
return ans
顺次数
代码:
class Solution {
public:
vector<int> sequentialDigits(int low, int high) {
vector<int>ans;
for(int len=1;len<10;len++){
for(int start = 1;start<11- len;start++){
int tmp = 0;
for(int i=start;i<start+len;i++){
tmp = tmp*10 + i;
}
if(tmp>=low&&tmp<=high) ans.push_back(tmp);
}
}
return ans;
}
};
class Solution:
def sequentialDigits(self, low, high):
ans = []
for len in range(1,10):
for start in range(1,10-len+1):
tmp = 0
for num in range(start, min(10,start + len)):
tmp = tmp *10 + num
if tmp>= low and tmp <=high:
ans.append(tmp)
return ans
元素和小于等于阈值的正方形的最大边长
题意:
在一个mxn矩阵里找到一个边长最长的正方形之和小于一个阈值。
思路:
首先,对矩阵预处理一下(容斥原理)实现 O(1) 求正方形之和 ,然后偷懒写法可以O(n)枚举边长,但O(n*m*min(n,m))
的复杂度python版本过不了,但c++能过(坑),所以更优的做法是二分边长,时间复杂度就变成O(n*m*log(min(n,m)))
。
看来leetcode 用 python 做题要更细致的考虑时间复杂度…
代码:
c++ 版 O(n*m*min(n,m))
复杂度 332 ms
class Solution {
private:
int a[305][305];
long long s[305][305];
public:
int maxSideLength(vector<vector<int>>& mat, int threshold) {
int n = mat.size();
int m = mat[0].size();
memset(s, 0, sizeof s);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j) {
a[i][j] = mat[i - 1][j - 1];
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
}
int ans = 0;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j) {
for (int k = 1; k <= i && k <= j; ++k)
if (s[i][j] - s[i - k][j] - s[i][j - k] + s[i - k][j - k] <= threshold)
ans = max(ans, k);
}
return ans;
}
};
C++ 版 O(n*m*log(min(n,m)))
复杂度 108 ms
class Solution {
private:
int a[305][305];
long long s[305][305];
public:
int maxSideLength(vector<vector<int>>& mat, int threshold) {
int n = mat.size();
int m = mat[0].size();
memset(s, 0, sizeof s);
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j) {
a[i][j] = mat[i - 1][j - 1];
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];
}
int ans = 0;
int l =0, r =min(n,m);
while(l<=r){
int k = (l+r)/2;
int ok = 0;
for (int i = k; i <= n; ++i){
for (int j = k; j <= m; ++j) {
if (s[i][j] - s[i - k][j] - s[i][j - k] + s[i - k][j - k] <= threshold){
ans = max(ans, k);
ok = 1;
}
}
}
if(ok==1) l = k +1;
else r = k -1;
}
return ans;
}
};
Python版 O(n*m*log(min(n,m)))
复杂度 1404 ms
class Solution:
def maxSideLength(self, mat, threshold) :
n, m = len(mat) , len(mat[0])
#print('n:', n , 'm:', m)
sum = [ [0] * (m+1) for i in range(n+1)]
a = [ [0] * (m+1) for i in range(n+1)]
for i in range(1,n+1):
for j in range(1,m+1):
a[i][j] = mat[i-1][j-1]
sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + a[i][j]
ans = 0
l = 0 ; r = min(n,m);
while l <=r :
d = int((l+r)/2)
flag = False
for i in range(d,n+1):
for j in range(d,m+1):
# for d in range(1,min(i+1 ,j+1)): # python如果不二分就会超时
num = sum[i][j] - sum[i-d][j] - sum[i][j-d] + sum[i-d][j-d]
if num <= threshold:
ans = max(ans, d)
flag = True
if flag:
l = d +1
else :
r = d -1
return ans
网格中的最短路径
题意:
有障碍的迷宫,给k次机会破除障碍的机会,问最少步数从(0,0)出发走到(n-1,m-1)。
思路:
多用一个状态记录当前破除过几次障碍的的广搜(dfs),实际上由于广搜的特点,第一次到达出口的步数就是最后的答案。
这里有个插曲,数据的问题从(0,0)到(n-1,m-1),广搜的四个方向的顺序会影响程序的效率(最优先向下右),因为这个问题,python版本我TLE了一发。
代码:
class Solution {
public:
struct node{
int x,y,k;
node(){}
node(int _x, int _y, int _k) {x = _x; y = _y; k = _k;}
};
int shortestPath(vector<vector<int>>& grid, int k) {
queue<node>q;
int n = grid.size(),m = grid[0].size();
int step[n+10][m+10][k+10];
memset(step,-1,sizeof(step));
if(grid[0][0] == 1){
q.push(node(0,0,1));
}
else{
q.push(node(0,0,0));
}
step[0][0][0] = 0;
while(!q.empty()){
node now = q.front(); q.pop();
if(now.x == n-1 && now.y ==m-1){
return step[now.x][now.y][now.k];
}
int nxt[4][2] = {{0,1},{1,0},{-1,0},{0,-1}};
for(int i=0;i<4;i++){
int nx = now.x + nxt[i][0];
int ny = now.y + nxt[i][1];
if(nx>=0&&nx<n&&ny>=0&&ny<m){
int nk = now.k + grid[nx][ny];
if(nk<=k&&step[nx][ny][nk]==-1){
step[nx][ny][nk] = step[now.x][now.y][now.k] + 1;
//cout<<nx<<" "<<ny<<" "<<nk<<" "<<step[nx][ny][nk]<<endl;
q.push(node(nx,ny,nk));
}
}
}
}
return -1;
}
};
class Solution:
def shortestPath(self, grid, k) :
t = 0
vis = set()
n, m = len(grid),len(grid[0])
if grid[0][0] == 1:
q = [(0,0,0,1)]
vis.add((0,0,1))
else :
q = [(0,0,0,0)]
vis.add((0,0,0))
while t< len(q):
now = q[t]
t+=1
if now[0] == n - 1 and now[1] == m - 1: return now[2]
for step in [[0,1],[1,0],[-1,0],[0,-1]]:
nx = now[0] + step[0]
ny = now[1] + step[1]
#print(nx,ny)
if 0 <= nx < n and 0 <= ny< m:
nk = now[3] + grid[nx][ny]
if nk <= k:
if (nx, ny, nk) not in vis:
#print(nx,ny,nk)
vis.add((nx, ny, nk))
q.append((nx, ny, now[2] + 1, nk))
return -1