LeetCode刷题记录
Posted 萌萌滴太阳
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode刷题记录相关的知识,希望对你有一定的参考价值。
文章目录
DFS/BFS
365. 水壶问题
- 关键是下面6个状态的列出
可以看出,可用搜索算法,DFS或BFS;
在「树」上的「深度优先遍历」就是「回溯算法」,在「图」上的「深度优先遍历」是「flood fill」 算法,深搜比较节约空间。这道题由于就是要找到一个符合题意的状态,我们用广搜就好了。这是因为广搜有个性质,一层一层像水波纹一样扩散,路径最短。
另外,在每一步搜索时,我们会依次尝试所有的操作,递归地搜索下去。这会导致超时,因此需要剪枝
;
因此我们还需要使用一个哈希集合(HashSet)存储所有已经搜索过但不符合条件的 remain_x, remain_y 状态,这样如果搜索的状态在HashSet里有,这个状态就不用再判断了,因为以前判断过,不符合条件,保证每个状态至多只被搜索一次。
- BFS的模板如下:
vector<vector<int>> levelOrder(TreeNode* root)
//1、初始化:一个队列queue<TreeNode*> q, 将root节点入队列
queue<TreeNode*> q;
q.push(root);
//2、如果队列不空(每次判断的队列,其包含二叉树同一层节点),做如下操作:
while(q.size())
int size=q.size();
//...
for(int i=0;i<size;i++)
///3、弹出队列头,保存为node,将node的左右非空孩子加入队列
TreeNode* rt=q.front();q.pop();
//...
if(rt->left) q.push(rt->left);
if(rt->right) q.push(rt->right);
//return ...
代码:
class Solution
public boolean canMeasureWater(int jug1Capacity, int jug2Capacity, int targetCapacity)
int x = jug1Capacity;
int y = jug2Capacity;
Queue<int[]> q = new LinkedList<int[]>();
HashSet<Long> visited = new HashSet<Long>();
q.add(new int[]0 , 0);
while(q.size() > 0)
int size = q.size();
for(int i = 0 ; i < size ; i++)
int[] temp = q.poll();
int remian_x = temp[0];
int remian_y = temp[1];
if(visited.contains(hashCode(remian_x , remian_y))) continue;
if(remian_x == targetCapacity || remian_y == targetCapacity || (remian_x + remian_y) == targetCapacity)
return true;
q.add(new int[]remian_x - Math.min(remian_x , y - remian_y) , remian_y + Math.min(remian_x , y - remian_y));
q.add(new int[]remian_x + Math.min(remian_y , x - remian_x) , remian_y - Math.min(remian_y , x - remian_x));
q.add(new int[]0 , remian_y);
q.add(new int[]x , remian_y);
q.add(new int[]remian_x , 0);
q.add(new int[]remian_x , y);
visited.add(hashCode(remian_x , remian_y));
return false;
long hashCode(int a , int b)
return (long) a * 1000001 + b;
- 封装一个State类
class Solution
public boolean canMeasureWater(int jug1Capacity, int jug2Capacity, int targetCapacity)
int x = jug1Capacity;
int y = jug2Capacity;
Queue<State> q = new LinkedList<State>();
HashSet<State> visited = new HashSet<State>();
q.add(new State(0 , 0));
while(q.size() > 0)
int size = q.size();
for(int i = 0 ; i < size ; i++)
State state = q.poll();
int remian_x = state.getX();
int remian_y = state.getY();
if(visited.contains(state)) continue;
if(remian_x == targetCapacity || remian_y == targetCapacity || (remian_x + remian_y) == targetCapacity)
return true;
q.add(new State(remian_x - Math.min(remian_x , y - remian_y) , remian_y + Math.min(remian_x , y - remian_y)));
q.add(new State(remian_x + Math.min(remian_y , x - remian_x) , remian_y - Math.min(remian_y , x - remian_x)));
q.add(new State(0 , remian_y));
q.add(new State(x , remian_y));
q.add(new State(remian_x , 0));
q.add(new State(remian_x , y));
visited.add(state);
return false;
public class State
private int x;
private int y;
public State()
public State(int x, int y)
this.x = x;
this.y = y;
public int getX()
return x;
public void setX(int x)
this.x = x;
public int getY()
return y;
public void setY(int y)
this.y = y;
@Override
public boolean equals(Object o)
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
State state = (State) o;
return x == state.x &&
y == state.y;
@Override
public int hashCode()
return Objects.hash(x, y);
@Override
public String toString()
return "State" +
"x=" + x +
", y=" + y +
'';
ZJ
ZJ1 附加题
-
DP
-
解析
import java.util.*;
public class Main
public static void main(String args[])
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int mod = 1000000007;
int[] dp = new int[n + 2];
int[] pi = new int[n + 1];
dp[1] = 0;
for(int i = 1 ; i <= n ; i++)
pi[i] = sc.nextInt();
for(int i = 2 ; i <= n + 1; i++)
dp[i] = (dp[i - 1] + (dp[i - 1] - dp[pi[i - 1]] + 1) + 1) % mod;
dp[n + 1] = dp[n + 1] > 0 ? dp[n + 1] : dp[n + 1] + mod;
System.out.print(dp[n + 1]);
圆环回原点问题
参考 https://mp.weixin.qq.com/s/NZPaFsFrTybO3K3s7p7EVg
圆环上有10个点,编号为0~9。从0点出发,每次可以逆时针和顺时针走一步,问走n步回到0点共有多少种走法。
输入: 2
输出: 2
解释:有2种方案。分别是0->1->0和0->9->0
- python
class Solution:
def backToOrigin(self,n):
#点的个数为10
length = 10
//多开一位
dp = [[0 for i in range(length)] for j in range(n+1)]
//经过验算,只需dp[0][0] = 1 其它dp[0][j] = 0;
dp[0][0] = 1
for i in range(1,n+1):
for j in range(length):
#dp[i][j]表示从0出发,走i步到j的方案数
dp[i][j] = dp[i-1][(j-1+length)%length] + dp[i-1][(j+1)%length]
return dp[n][0]
- java
class Solution
public int solve(int n)
int len = 10;
int[][] dp = new int[n+1][len];
//经过验算,只需dp[0][0] = 1 其它dp[0][j] = 0;
dp[0][0] = 1;
for(int i = 1 ; i <= n ; i++)
for(int j = 0 ; j < len ; j ++)
dp[i][j] = dp[i-1][(j-1+length)%length] + dp[i-1][(j+1)%length];
return dp[n][0];
以上是关于LeetCode刷题记录的主要内容,如果未能解决你的问题,请参考以下文章
[JavaScript 刷题] 排序 - 最接近原点的 K 个点, leetcode 973