数组中重复数字
public static int findRepeatNumber(int[] nums) {
int length = nums.length;
Map<Integer,Integer> map = new HashMap<>();
for (int i=0;i<length;i++){
map.put(i,0);
}
for (int item:nums){
int a= map.get(item);
if (a==1) return item;
a++;
map.put(item,a);
}
return -1;
}
4二维数组中查找
public static boolean findNumberIn2DArray(int[][] matrix, int target) {
if (matrix==null)return false;
int rows = matrix.length;
if (rows ==0) return false;
int columns = matrix[0].length;
if (matrix!=null && rows >0 && columns>0){
int row = 0;
int column = columns-1;
while (row < rows && column >=0){
if (target == matrix[row][column]){
return true;
}else if (target>matrix[row][column]){
row++;
}else if (target<matrix[row][column]){
column--;
}
}
}
return false;
}
替换空格
public String replaceSpace(String s) {
String a = s.replace(" ","%20");//注意String是不可变的
return a;
}
从尾到头打印链表
public int[] reversePrint(ListNode head) {
LinkedList<Integer> linkedList = new LinkedList<>();
ListNode listNode = head;
while (listNode != null){
linkedList.addFirst(listNode.val);
listNode = listNode.next;
}
int[] ints = new int[linkedList.size()];
int i=0;
for (int item : linkedList){
ints[i++] = item;
}
return ints;
}
重建二叉树
public static TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder ==null || preorder.length ==0)
return null;
Map<Integer,Integer> indexMap = new HashMap<>();
int length = preorder.length;
for (int i=0;i<length;i++){
indexMap.put(inorder[i],i);
}
TreeNode hand =buildTree(preorder,0,length-1,inorder,0,length-1,indexMap);
return hand;
}
public static TreeNode buildTree(int[] preorder,int preorderStart,int preorderEnd,int[] inorder,int inorderstart,int inorderEnd,Map<Integer,Integer> indexMap)
{
if (preorderStart > preorderEnd){
return null;
}
int rootval = preorder[preorderStart];
TreeNode root = new TreeNode(rootval);
if (preorderStart == preorderEnd){
return root;
}else {
int rootindex = indexMap.get(rootval);
int leftNodes = rootindex - inorderstart;
int rightNode = inorderEnd - rootindex;
TreeNode leftSubtree = buildTree(preorder,preorderStart+1,preorderStart+leftNodes,inorder,inorderstart,rootindex-1,indexMap);
TreeNode rightSbutree = buildTree(preorder,preorderEnd-rightNode+1,preorderEnd,inorder,rootindex+1,inorderEnd,indexMap);
root.left = leftSubtree;
root.right = rightSbutree;
return root;
}
}
斐波那契
public static int fib(int n) {
ArrayList<Integer> list = new ArrayList<>();
list.add(0);
list.add(1);
if (n==0) return 0;
if (n==1) return 1;
for (int i=2;i<=n;i++){
Integer integer = list.get(i - 1);
Integer integer1 = list.get(i - 2);
list.add((integer + integer1)%1000000007);//这里需要取余
}
return list.get(n);
}
青蛙跳台
public int numWays(int n) {
List<Integer> arrayList = new ArrayList<>();
arrayList.add(0);
arrayList.add(1);
arrayList.add(2);
if (n==0) return 1;
if (n==1) return 1;
if (n==2) return 2;
for (int i=3;i<=n;i++){
Integer integer = arrayList.get(i - 1);
Integer integer1 = arrayList.get(i - 2);
Integer a = (integer + integer1)%1000000007;
arrayList.add(a);
}
return arrayList.get(n);
}
旋转数组的最小值
public int minArray(int[] numbers) {
int length = numbers.length;
for (int i=length-1; i>0; i--){
if (numbers[i] < numbers[i-1])
return numbers[i];
}
return numbers[0];
}
矩阵中的路径
public static boolean exist(char[][] board, String word) {
int rows = board.length;
int columns = board[0].length;
boolean[][] flag = new boolean[rows][columns];
char[] chars = word.toCharArray();
for (int i=0;i<rows;i++){
for (int j=0;j<columns;j++){
if (board[i][j] == chars[0]){
if (play(board,flag,chars,0,i,j)) {
return true;
}
}
}
}
return false;
}
public static boolean play(char[][] board,boolean[][] flag,char[] chars,int index,int i,int j){
if (i >= board.length || i< 0 || j >= board[0].length || j < 0 || board[i][j] != chars[index] || flag[i][j])
return false;
if (index == chars.length-1) return true;
flag[i][j] = true;
boolean res = play(board,flag,chars,index+1,i,j+1)||
play(board,flag,chars,index+1,i,j-1)||
play(board,flag,chars,index+1,i+1,j)||
play(board,flag,chars,index+1,i-1,j);
flag[i][j] = false;//关键 将返回路径重置
return res;
}
机器人的运动范围
public int movingCount(int m, int n, int k) {
if (k == 0){
return 1;
}
boolean[][] flag = new boolean[m][n];
int ans = 1;
flag[0][0] = true;
for (int i=0;i < m;i++){
for (int j=0;j < n;j++){
if ((i == 0 && j == 0) || get(i)+get(j) > k ){
continue;
}
if (i - 1 >=0){
flag[i][j] |= flag[i-1][j];
}
if (j - 1 >= 0){
flag[i][j] |= flag[i][j - 1];
}
ans += flag[i][j] ? 1 : 0;
}
}
return ans;
}
public int get(int x){
int res=0;
while (x != 0){
res += x%10;
x /=10;
}
return res;
}
剪绳子
public int cuttingRope(int n) {//贪心算法
if(n < 2) return 0;
if (n == 2) return 1;
if (n == 3) return 2;
int timesOf3 = n / 3;
if (n - timesOf3*3 ==1)
timesOf3 -=1;
int timesOf2 = (n - timesOf3*3) /2;
return (int) (Math.pow(3,timesOf3)*Math.pow(2,timesOf2));
}
public int cuttingRope(int n) {//动态规划
if (n < 2) return 0;
if (n == 2) return 1;
if (n == 3) return 2;
int[] products = new int[n+1];
products[0] = 0;
products[1] = 1;
products[2] = 2;
products[3] = 3;
int max =0;
for (int i = 4;i <= n;i++){
max = 0;
for (int j = 1;j <= i/2;j++){
int product = products[j]*products[i-j];
if (max < product)
max = product;
products[i] = max;
}
}
return products[n];
}
二进制中的1的个数
public int hammingWeight(int n) {//
String s = Integer.toBinaryString(n);
char[] chars = s.toCharArray();
int num = 0;
for (char item:chars){
if (item =='1') num++;
}
return num;
}
public static int hammingWeight(int n) {
int res = 0;
while(n != 0) {
res += n & 1;
n =n >>> 1;
}
return res;
}
数值的整数次方
public static double myPow(double x, int n) {//很笨
if (x == 1 && n > 0)
return 1;
if (x == 2 && n ==-2147483648)
return 0;
if (x == -1 && n == 2147483647)
return -1;
boolean flag = false;
if (n < 0) {
n = -n;
flag = true;
}
double res = 1;
for (int i=0;i<n;i++){
res *= x;
}
return flag ? 1/res:res;
}
public static double myPow(double x, int n) {
if (x == 0) return 0;
boolean flag = false;
if (n < 0){
flag = true;
n = -n;
}
double pow = pow(x, n);
return flag ? 1/pow : pow;
}
public static double pow(double x, int n){
if (n == 0) return 1;
if (n == 1) return x;
double pow = pow(x, n >>> 1);
pow *= pow;
if ((n & 0x1) ==1)//为奇数
pow *= x;
return pow;
}
链表中删除节点
public ListNode deleteNode(ListNode head, int val) {
if (head.val == val){
head = head.next;
return head;
}
ListNode r = head;
ListNode l = head.next;
while (l.val != val){
r = r.next;
l = l.next;
if (l == null) return head;
}
r.next = l.next;
return head;
}
调整数组顺序 奇数前 偶数后
public static int[] exchange(int[] nums) {
int left =0;
int right = nums.length -1;
while (left < right){
if ((nums[left] & 1) == 1){
left++;
continue;
}
if ((nums[right] & 1) == 0){
right--;
continue;
}
int item = nums[left];
nums[left] = nums[right];
nums[right] = item;
}
return nums;
}
链表中倒数第k个节点
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode h = head;
int length =0;
while (h != null){
h = h.next;
length++;
}
h = head;
int res = length - k;
for (int i =0 ;i < res ;i++){
h = h.next;
}
return h;
}
反转链表
public ListNode reverseList(ListNode head) {
if (head == null) return head;
ListNode h = new ListNode(head.val);
head = head.next;
while (head != null){
ListNode item = new ListNode(head.val);
item.next = h;
h = item;
head = head.next;
}
return h;
}
合并两个排序的链表
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode left = l1;
ListNode right = l2;
ListNode res;
if (l1 == null){
return l2;
}else if (l2 == null){
return l1;
}
if (l1.val < l2.val){
res = new ListNode(left.val);
left = left.next;
}else {
res = new ListNode(right.val);
right = right.next;
}
ListNode res1 = res;
while (left != null && right != null){
if (left.val < right.val){
res1.next = left;
res1 = left;
left = left.next;
}else {
res1.next = right;
res1 = right;
right = right.next;
}
}
if (left == null){
res1.next = right;
}else {
res1.next = left;
}
return res;
}
树的子结构
public boolean isSubStructure(TreeNode A, TreeNode B) {
if (A == null || B == null) return false;
return play(A,B) || isSubStructure(A.left,B) | isSubStructure(A.right,B);
}
public boolean play(TreeNode A,TreeNode B){
if(B == null) return true;
if (A == null || A.val != B.val) return false; // 判断顺序不可调换
return play(A.left,B.left) && play(A.right,B.right);
}
二叉树的镜像
TreeNode item;
public TreeNode mirrorTree(TreeNode root) {
if (root == null) return null;
return play(root);
}
public TreeNode play(TreeNode root){
if (root == null) return null;
item = root.left;
root.left = root.right;
root.right = item;
play(root.left);
play(root.right);
return root;
}
public TreeNode mirrorTree(TreeNode root) {
if (root == null) return null;
TreeNode item = root.left;
root.left = mirrorTree(root.right);
root.right = mirrorTree(item);
return root;
}
public TreeNode mirrorTree(TreeNode root) {
if (root == null) return null;
LinkedList<TreeNode> linkedList = new LinkedList<>();
linkedList.add(root);
while (!linkedList.isEmpty()){
TreeNode node = linkedList.pop();
if (node.left != null) linkedList.add(node.left);
if (node.right != null) linkedList.add(node.right);
TreeNode item = node.left;
node.left = node.right;
node.right = item;
}
return root;
}
对称二叉树
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
return play(root.left,root.right);
}
public boolean play(TreeNode left,TreeNode right){
if (left == null && right == null) return true;
if (left != null && right != null && left.val == right.val) return play(left.left,right.right ) && play(left.right,right.left);
return false;
}
从上到小打印二叉树 BFS广度优先算法
public int[] levelOrder(TreeNode root) {
if (root == null) return new int[0];
Queue<TreeNode> queue = new LinkedList<TreeNode>();
ArrayList<Integer> ans = new ArrayList<>();
queue.add(root);
while (!queue.isEmpty()){
TreeNode node = queue.poll();
ans.add(node.val);
if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right);
}
int[] res = new int[ans.size()];
for (int i =0 ; i < ans.size();i++){
res[i] = ans.get(i);
}
return res;
}
2
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
List<List<Integer>> res = new ArrayList<>();
if (root != null) queue.add(root);
while (!queue.isEmpty()){
List<Integer> tmp = new ArrayList<>();
for (int i = queue.size(); i > 0 ;i--){
TreeNode node = queue.poll();
tmp.add(node.val);
if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right);
}
res.add(tmp);
}
return res;
}
3
public List<List<Integer>> levelOrder(TreeNode root) {
Queue<TreeNode> queue = new LinkedList<>();
List<List<Integer>> list = new LinkedList<>();
if (root != null) queue.add(root);
boolean flag = true;
while (!queue.isEmpty()){
LinkedList<Integer> res = new LinkedList<>();
for (int i = queue.size(); i > 0 ;i--){
TreeNode node = queue.poll();
if (flag) {
res.addLast(node.val);
}else {
res.addFirst(node.val);
}
if (node.left != null) queue.add(node.left);
if (node.right != null) queue.add(node.right);
}
list.add(res);
if (flag) flag = false;
else flag = true;
}
return list;
}
二叉搜索树的后序遍历队列
public boolean verifyPostorder(int[] postorder) {
return recur(postorder,0,postorder.length-1);
}
boolean recur(int[] postorder,int i , int j){
if (i >= j) return true;
int p = i;
while (postorder[p] < postorder[j]) p++;
int m = p-1;
while (postorder[p] > postorder[j]) p++;
return p == j && recur(postorder,i,m) && recur(postorder,m+1,j-1);
}
二叉树中和为某一值的路径
LinkedList<List<Integer>> res = new LinkedList<>();
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> pathSum(TreeNode root, int sum) {
recur(root,sum);
return res;
}
public void recur(TreeNode root,int tar){
if (root == null) return;
path.addLast(root.val);
tar -= root.val;
if (tar ==0 && root.left == null && root.right == null){
res.add(new LinkedList<>(path));
}
recur(root.left,tar);
recur(root.right,tar);
path.removeLast();
}
复杂链表的复制
public Node copyRandomList(Node head) {
if (head == null) return null;
copy(head);
random(head);
return reList(head);
}
public void copy(Node head){
while (head != null){
Node clone = new Node(head.val);
Node nextHead = head.next;
head.next = clone;
clone.next = nextHead;
head = nextHead;
}
}
public void random(Node head){
while (head != null){
Node nextNode = head.next;
if (head.random != null){
Node nextRandom = head.random;
nextNode.random = nextRandom.next;
}
head = nextNode.next;
}
}
public Node reList(Node head){
Node h = head.next;
head.next = h.next;
head = head.next;
Node item = h;
while (head != null){
item.next = head.next;
head.next = head.next.next;
head = head.next;
item = item.next;
}
return h;
}
public Node copyRandomList(Node head) {
if (head == null) return null;
HashMap<Node ,Node> hashMap = new HashMap<>();
Node item = head;
while (item != null){
hashMap.put(item,new Node(item.val));
item = item.next;
}
item = head;
while (item != null){
hashMap.get(item).next = hashMap.get(item.next);
hashMap.get(item).random = hashMap.get(item.random);
item = item.next;
}
return hashMap.get(head);
}
二叉搜索树与双向链表
Node pre , head;
public Node treeToDoublyList(Node root) {
if (root == null) return null;
dfs(root);
head.left = pre;
pre.right = head;
return head;
}
public void dfs(Node cur){
if (cur == null) return;
dfs(cur.left);
if (pre != null) pre.right = cur;
else head = cur;
cur.left = pre;
pre = cur;
dfs(cur.right);
}
序列化二叉树
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
if (root == null)
return "#";
Queue<TreeNode> queue = new LinkedList<>();
StringBuilder res = new StringBuilder();
queue.add(root);
while (!queue.isEmpty()){
TreeNode node = queue.poll();
if (node == null){
res.append("#,");
continue;
}
res.append(node.val+",");
queue.add(node.left);
queue.add(node.right);
}
return res.toString();
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if (data == "#"){
return null;
}
Queue<TreeNode> queue = new LinkedList<>();
String[] values = data.split(",");
TreeNode root = new TreeNode(Integer.parseInt(values[0]));
queue.add(root);
for (int i=1;i < values.length;i++){
TreeNode node = queue.poll();
if (!"#".equals(values[i])){
TreeNode left = new TreeNode(Integer.parseInt(values[i]));
node.left = left;
queue.add(left);
}
if (!"#".equals(values[++i])){
TreeNode right = new TreeNode(Integer.parseInt(values[i]));
node.right = right;
queue.add(right);
}
}
return root;
}
二叉树的深度
public int maxDepth(TreeNode root) {
if (root == null) return 0;
return Math.max(maxDepth(root.left),maxDepth(root.right))+1;
}
public int maxDepth(TreeNode root) {
if (root == null) return 0;
List<TreeNode> queue = new LinkedList<>(),tmp;
queue.add(root);
int depth = 0;
while (!queue.isEmpty()){
tmp = new LinkedList<>();
for (TreeNode item : queue){
if (item.left != null) tmp.add(item.left);
if (item.right != null) tmp.add(item.right);
}
queue = tmp;
depth++;
}
return depth;
}
二叉搜索树的第k大的数
int res , k;
public int kthLargest(TreeNode root, int k) {//中序遍历的后续遍历
this.k = k;
max(root);
return res;
}
public void max(TreeNode root){
if (root == null) return;
max(root.right);
if (k == 0) return;
if (--k == 0) res = root.val;
max(root.left);
}
平衡二叉树
public boolean isBalanced(TreeNode root) {
if (root == null){
return true;
}else {
return Math.abs(height(root.left) - height(root.right)) <= 1 && isBalanced(root.left) && isBalanced(root.right);
}
}
public int height(TreeNode root){
if (root == null){
return 0;
}else {
return Math.max(height(root.left),height(root.right))+1;
}
}
二叉搜索树的最近公共祖先
//迭代 两个节点在同一边,则遍历这一边,如果在异侧则返回
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
while (root != null){
if (root.val < p.val && root.val < q.val)
root = root.right;
else if (root.val > p.val && root.val > q.val)
root = root.left;
else break;
}
return root;
}
//递归 如果在root节点的同侧,则递归这一侧,否则返回
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root.val < p.val && root.val < q.val)
return lowestCommonAncestor(root.right,p,q);
if (root.val > p.val && root.val > q.val)
return lowestCommonAncestor(root.left,p,q);
return root;
}
二叉树的最近公共祖先
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) return null;
if (root == p || root == q) return root;
TreeNode left = lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);
if (left == null) return right;// 如果在左子树中 p和 q都找不到,则 p和 q一定都在右子树中,右子树中先遍历到的那个就是最近公共祖先(一个节点也可以是它自己的祖先)
else if (right == null) return left;// 否则,如果 left不为空,在左子树中有找到节点(p或q),这时候要再判断一下右子树中的情况,如果在右子树中,p和q都找不到,则 p和q一定都在左子树中,左子树中先遍历到的那个就是最近公共祖先(一个节点也可以是它自己的祖先)
else return root;//否则,当 left和 right均不为空时,说明 p、q节点分别在 root异侧, 最近公共祖先即为 root
}
!@#¥%……&*()——+12.12.22