1.构建自己的循环队列
/*
课本原题
*/
public class MyCircularQueue {
private int[] data;
private int head;
private int tail;
private int size;
public MyCircularQueue(int k) {
data = new int[k];
head = -1;
tail = -1;
size = k;
}
public boolean enQueue(int value) {
if (isFull() == true) {
return false;
}
if (isEmpty() == true) {
head = 0;
}
tail = (tail + 1) % size;
data[tail] = value;
return true;
}
public boolean deQueue() {
if (head==tail&&head==-1){
return false;
}
//当只剩下一个元素时
else if (head==tail){
head = -1;
tail = -1;
return true;
}else {
head = (head+1)%size;
return true;
}
}
public int Front() {
if (isEmpty()==true){
return -1;
}
return data[head];
}
public int Rear() {
if (isEmpty()==true){
return -1;
}
return data[tail];
}
public boolean isEmpty() {
return head==-1;
}
public boolean isFull() {
return ((tail + 1) % size) == head;
}
}
2.利用定义好的库中的队列
public class Que {
public static void main(String[] args) {
Queue<Integer> queue = new LinkedList<Integer>();
System.out.println(queue.peek());
queue.add(1);
System.out.println(queue.peek());
}
}
3.岛屿数量:看着题目挺难懂,但是看一下测试用例就明白了,岛屿即连在一起的1,岛屿的数量就是有多少个连在一起的集合1。
/*
执行用时:3 ms, 在所有 Java 提交中击败了47.42%的用户
内存消耗:41.8 MB, 在所有 Java 提交中击败了6.25%的用户
*/
public class Solution {
public int numIslands(char[][] grid) {
if (grid == null || grid.length == 0) return 0;
int count = 0;//记录岛屿的数量
int row = grid.length, colums = grid[0].length;
int i, j;
for (i = 0; i < row; i++) {
for (j = 0; j < colums; j++) {
if (grid[i][j] == '1') {
bfs(row, colums, i, j, grid);
count++;
}
}
}
return count;
}
//利用队列,进行广度优先遍历,将连在一起的1变成0.
private void bfs(int row, int colums, int i, int j, char[][] grid) {
//利用队列存储位置
Queue<Integer> queue= new LinkedList<Integer>();
queue.add(i*colums+j);
//分析上下左右是否为1
while (!queue.isEmpty()){
int temp = queue.remove();
int a = temp/colums, b = temp%colums;
grid[a][b]=0;
if (a-1>=0&&grid[a-1][b]=='1'){
queue.add((a-1)*colums+b);
grid[a-1][b]='0';
}
if (a+1<row&&grid[a+1][b]=='1'){
queue.add((a+1)*colums+b);
grid[a+1][b]='0';
}
if (b-1>=0&&grid[a][b-1]=='1'){
queue.add(a*colums+b-1);
grid[a][b-1]='0';
}
if (b+1<colums&&grid[a][b+1]=='1'){
queue.add(a*colums+b+1);
grid[a][b+1]='0';
}
}
}
}
4.二叉树的最小高度:利用labuladong大佬的框架
/*
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:39.8 MB, 在所有 Java 提交中击败了5.13%的用户
*/
public class Solution {
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
//offer、poll当出现异常时会返回false,而add,remove会抛出异常
public int minDepth(TreeNode root) {
if (root==null) return 0;
Queue<TreeNode> treeNodes = new LinkedList<TreeNode>();
treeNodes.offer(root);
int count = 1;
while(!treeNodes.isEmpty()){
int len = treeNodes.size();
int i ;
for(i=0;i<len;i++){
TreeNode node = treeNodes.poll();
if (node.left==null&&node.right==null){
return count;
}
if (node.left!=null){
treeNodes.offer(node.left);
}
if (node.right!=null){
treeNodes.offer(node.right);
}
}
//当循环完树的一层时,层数加一
count++;
}
return count;
}
}
5.打开转盘锁(单向BFS:利用labuladong大佬的框架)
/*
执行用时:90 ms, 在所有 Java 提交中击败了77.25%的用户
内存消耗:45.6 MB, 在所有 Java 提交中击败了16.67%的用户
*/
class Solution {
//进行转盘锁状态转移,每位数字进行加1或减1操作
String up(int i, String s) {
char[] ss = s.toCharArray();
if (ss[i] == '9') {
ss[i] = '0';
} else {
ss[i] += 1;
}
return new String(ss);
}
String down(int i, String s) {
char[] ss = s.toCharArray();
if (ss[i] == '0') {
ss[i] = '9';
} else {
ss[i] -= 1;
}
return new String(ss);
}
int openLock(String[] deadends, String target) {
//记录死亡数字
Set<String> deads = new HashSet<String>();
for (String s : deadends) deads.add(s);
//记录浏览过的数字,减少循环
Set<String> visited = new HashSet<>();
Queue<String> queue = new LinkedList<String>();
queue.offer("0000");
visited.add("0000");
int count = 0;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
String s = queue.poll();
//当死亡数字包含S时,跳过该数字以及该数字每位加1或减1的数字,进行下一位数字判断。
if (deads.contains(s)) {
continue;
}
if (s.equals(target)) {
return count;
}
//对每位数字上的4位进行加1或减1操作
for (int j = 0; j < 4; j++) {
String data = up(j, s);
if (!visited.contains(data)) {
queue.offer(data);
visited.add(data);
}
data = down(j, s);
if (!visited.contains(data)) {
queue.offer(data);
visited.add(data);
}
}
}
count++;
}
//当循环完成都没找到的话,就说明没有方法能转到该数字
return -1;
}
}
6.打开转盘锁(双向BFS:利用labuladong大佬的框架)
传统的 BFS 框架就是从起点开始向四周扩散,遇到终点时停止;而双向 BFS 则是从起点和终点同时开始扩散,当两边有交集的时候停止,但是双向BFS必须知道重点在哪,例如求二叉树的最小高度就不能用双向BFS.
/*
执行用时:31 ms, 在所有 Java 提交中击败了92.17%的用户
内存消耗:40.4 MB, 在所有 Java 提交中击败了33.33%的用户
*/
class Solution {
String up(int i, String s) {
char[] ss = s.toCharArray();
if (ss[i] == '9') {
ss[i] = '0';
} else {
ss[i] += 1;
}
return new String(ss);
}
String down(int i, String s) {
char[] ss = s.toCharArray();
if (ss[i] == '0') {
ss[i] = '9';
} else {
ss[i] -= 1;
}
return new String(ss);
}
int openLock(String[] deadends, String target) {
Set<String> deads = new HashSet<>();
for (String s : deadends) deads.add(s);
// 用集合不用队列,可以快速判断元素是否存在
Set<String> q1 = new HashSet<>();
Set<String> q2 = new HashSet<>();
Set<String> visited = new HashSet<>();
int step = 0;
q1.add("0000");
q2.add(target);
while (!q1.isEmpty() && !q2.isEmpty()) {
// 哈希集合在遍历的过程中不能修改,用 temp 存储扩散结果
Set<String> temp = new HashSet<>();
/* 将 q1 中的所有节点向周围扩散 */
for (String cur : q1) {
/* 判断是否到达终点 */
if (deads.contains(cur))
continue;
if (q2.contains(cur))
return step;
visited.add(cur);
/* 将一个节点的未遍历相邻节点加入集合 */
for (int j = 0; j < 4; j++) {
String data = up(j, cur);
if (!visited.contains(data)) {
temp.add(data);
}
data = down(j, cur);
if (!visited.contains(data)) {
temp.add(data);
}
}
}
/* 在这里增加步数 */
step++;
// temp 相当于 q1
// 这里交换 q1 q2,下一轮 while 就是扩散 q2
q1 = q2;
q2 = temp;
}
return-1;
}
}
7.完全平方数(如下面图片你所示)
/*
执行用时:336 ms, 在所有 Java 提交中击败了9.59%的用户
内存消耗:262.4 MB, 在所有 Java 提交中击败了5.26%的用户
*/
class Solution {
public int numSquares(int n) {
if (n==0) return 0;
//利用nums存储值小于等于n完全平方数
ArrayList<Integer> nums = new ArrayList<Integer>();
for (int i =1;i*i<=n;i++){
nums.add(i*i);
}
Queue<Integer> queue = new LinkedList<Integer>();
queue.add(n);
int count = 1;
while(!queue.isEmpty()){
int size = queue.size();
for (int i=0;i<size;i++){
Integer temp = queue.remove();
for (Integer integer:nums){
//当某一层的数等于完全平方数时,即找到了答案
if (temp.equals(integer)){
return count;
}else if (temp<integer){
continue;
}else {
queue.add(temp-integer);
}
}
}
count++;
}
return count;
}
}