• 算法-题目汇总-6


    1. 某个数是否存在于二维数组中

     1 public boolean search(int[][] m, int target) {
     2         if (m.length == 0 || m[0].length == 0) {
     3             return false;
     4         }
     5         int l = 0;
     6         int r = m.length * m[0].length - 1;
     7         int col = m[0].length;
     8         while (l <= r) {
     9             int mid = l + ((r - l) >> 1);
    10             // mid/col 求出在哪行
    11             // mid%col 求出在哪列
    12             int val = m[mid / col][mid % col];
    13             if (val == target) {
    14                 return true;
    15             } else if (val < target) {
    16                 l = mid + 1;
    17             } else {
    18                 r = mid - 1;
    19             }
    20         }
    21         return false;
    22     }

     2. 前序中序转树

     1 public TreeNode getTree(int[] pre, int[] mid) {
     2         return process(pre, 0, pre.length - 1, mid, 0, mid.length - 1);
     3     }
     4 
     5     public TreeNode process(int[] pre, int pl, int pr, int[] mid, int ml, int mr) {
     6         if (pl > pr || ml > mr) {
     7             return null;
     8         }
     9         int value = pre[pl];
    10         int help = ml;
    11         while (help < mr &&  mid[help] != value) {
    12             help++;
    13         }
    14         TreeNode treeNode = new TreeNode(value);
    15         treeNode.left = process(pre, pl + 1, pl + help - ml, mid, ml,help - 1);
    16         treeNode.right = process(pre, pl + help - ml + 1, pr, mid, help + 1, mr);
    17         return treeNode;
    18     }

    3. 可循环的数组找最小值

     1 public int search(int[] arr) {
     2         if (arr.length == 0) {
     3             return -1;
     4         }
     5         int l = 0;
     6         int r = arr.length - 1;
     7         if (arr[r] > arr[0] || arr[r] == arr[0]) {
     8             return arr[0];
     9         }
    10         while (l <= r) {
    11             int mid = l + ((r - l) >> 1);
    12             // 可以举例得出结论
    13             if (arr[mid] > arr[mid + 1]) {
    14                 return arr[mid + 1];
    15             }
    16             if (arr[mid - 1] > arr[mid]) {
    17                 return arr[mid];
    18             }
    19             // 中间值大于0位置的值 说明
    20             if (arr[mid] > arr[0]) {
    21                 l = mid + 1;
    22             } else {
    23                 r = mid - 1;
    24             }
    25         }
    26         return -1;
    27     }

    4. 统计整数 二进制形式有多少个1 (n-1)&n 可以将最右边的1设置为0

      

     1  public int count(int n) {
     2         int count = 0;
     3         if (n == 0) {
     4             return count;
     5         }
     6         while (n != 0) {
     7             count++;
     8             n = (n - 1) & n;
     9         }
    10         return count;
    11     }

     5. 获取链表的倒数第k个节点

     1 public ListNode getLastKNode(ListNode head, int k) {
     2         if (head == null || k < 1) {
     3             return null;
     4         }
     5         ListNode fast = head;
     6         ListNode slow = head;
          // 注意k-- 要大于1 才能获取到最后一个node
    7 while (k-- > 1) { 8 if (fast.next == null) { 9 return null; 10 } 11 fast = fast.next; 12 } 13 while (fast.next != null) { 14 fast = fast.next; 15 slow = slow.next; 16 } 17 return slow; 18 }

    6. 子树判断

     1 public boolean checkSubTree(TreeNode t1, TreeNode t2) {
     2         if (t1 == null) {
     3             return false;
     4         }
     5         if (t2 == null) {
     6             return true;
     7         }
     8         return isSame(t1, t2) || checkSubTree(t1.left, t2) || checkSubTree(t2.right, t2);
     9     }
    10 
    11     public boolean isSame(TreeNode t1, TreeNode t2) {
    12         if (t1 == t2) {
    13             return true;
    14         }
    15         if (t1 == null || t2 == null) {
    16             return false;
    17         }
    18 
    19         return t1.val == t2.val && isSame(t1.left, t2.left) && isSame(t1.right, t2.right);
    20     }
     1 class Solution {
     2     public boolean checkSubTree(TreeNode t1, TreeNode t2) {
     3         
     4         if(t1 == null){
     5             if(t2 == null){
     6                 return true;
     7             }else{
     8                 return false;
     9             }
    10         }
    11         //判断当前节点是否符合,递归先序左孩子,递归先序右孩子
    12         return recur(t1, t2) || checkSubTree(t1.left, t2) || checkSubTree(t1.right, t2);
    13     }
    14 
    15     //递归判断两颗树是否完全相同
    16     boolean recur(TreeNode root1, TreeNode root2){
    17 
    18         if(root1 == null && root2 == null){
    19             return true;
    20         }
    21 
    22         if(root1 == null || root2 == null){
    23             return false;
    24         }
    25 
    26         if(root1.val != root2.val){
    27             return false;
    28         }
    29 
    30         return recur(root1.left, root2.left) && recur(root1.right, root2.right);
    31 
    32     }
    33 }

    7. 给你一个数组 判断数组的序列是否是搜索二叉树的后续序列

     数组的最后一个数肯定是root节点,小于root值的数是左子树,大于root值的是右子树

      找到左右子树的范围再递归判断

     1 public boolean judgeBst(int[] arr) {
     2         return isBst(arr, 0, arr.length - 1);
     3     }
     4 
     5     public boolean isBst(int[] arr, int l, int r) {
     6         if (l >= r) {
     7             return true;
     8         }
     9         int i = l;
    10         while (arr[i] < arr[r]) {
    11             i++;
    12         }
    13         for (int j = i; j <= r; j++) {
    14             if (arr[j] < arr[r]) {
    15                 return false;
    16             }
    17         }
    18         return isBst(arr, l, i - 1) &&
    19                 isBst(arr, i, l - 1);
    20     }

    8. 二叉树 返回指定数值的节点路径 必须是到叶子节点才能算一条路径

     1 public class FindPath {
     2     private ArrayList<Integer> list = new ArrayList<>();
     3     private ArrayList<ArrayList<Integer>> res = new ArrayList<>();
     4 
     5     public ArrayList<ArrayList<Integer>> findPath(TreeNode head, int k) {
     6         process(head, k);
     7         return res;
     8     }
     9 
    10     public void process(TreeNode head, int rest) {
    11         if (head == null) {
    12             return;
    13         }
    14         list.add(head.val);
    15         rest -= head.val;
    16         if (rest == 0 && head.left == null && head.right == null) {
    17             res.add(new ArrayList<>(list));
    18         }
    19         process(head.left, rest);
    20         process(head.right, rest);
          // 返回父节点的时候删除子节点的值
    21 list.remove(list.size() - 1); 22 } 23 }

     9.复杂链表复制

      思路1: 先根据next复制在复制过程中 用hashmap记录随机的node值 组成next链表之后再遍历设置随机node

      思路2: 遍历链表 复制node A-B-C 复制成A-A`-B-B`-C-C` 然后遍历链表A`的随机node 是Anode的随机node+1  然后再把链表分成两个链表

      

     1 public ListNode copy(ListNode head) {
     2         cloneNodes(head);
     3         connectSiblingNodes(head);
     4         return split(head);
     5     }
     6 
     7     public void cloneNodes(ListNode head) {
     8         ListNode p = head;
     9         while (p != null) {
    10             ListNode newNode = new ListNode(p.val);
    11             newNode.next = p.next;
    12             p.next = newNode;
    13             p = newNode.next;
    14         }
    15     }
    16 
    17     public void connectSiblingNodes(ListNode head) {
    18         ListNode p = head;
    19         while (p != null) {
    20             ListNode pclone = p.next;
    21             ListNode rNext = p.rNext;
    22             if (rNext != null) {
    23                 pclone.rNext = rNext.next;
    24             }
    25             p = pclone.next;
    26         }
    27     }
    28 
    29     public ListNode split(ListNode head) {
    30         ListNode node = head;
    31         ListNode cloneHead = null;
    32         ListNode cloneNode = null;
    33         if (head != null) {
    34             cloneHead = cloneNode = node.next;
    35             node.next = cloneNode.next;
    36             node = node.next;
    37         }
    38         while (node != null) {
    39             cloneNode.next = node.next;
    40             cloneNode = cloneNode.next;
    41 
    42             node.next = cloneNode.next;
    43             node = node.next;
    44         }
    45         return cloneHead;
    46     }

    10. 求第n个丑数/ 判断这个数是否是丑数

      丑数先被2除 然后被5除 然后被3除 等于1是丑数

      n%2==0 n/2

      n%5 ==0 n/5

      n%3 == 0 n/3

         求第n个丑数,第一个丑数是1 第二个丑数是前一个丑数*234的最小值,每次计算出丑数之后 更新p2 p3 p5的值会增加效率 指针要知道刚好等于或小于最后一个丑数的位置

      

     1 public int get(int n) {
     2         if (n < 1) {
     3             return -1;
     4         }
            // 小于7的丑数就是自己
    5 if (n < 7) { 6 return n; 7 } 8 int p2 = 0, p3 = 0, p5 = 0; 9 int[] help = new int[n]; 10 help[0] = 1; 11 for (int i = 1; i < n; i++) { 12 help[i] = Math.min(Math.min(help[p2] * 2, help[p3] * 3), help[p5] * 5); 13 while (help[p2] * 2 <= help[i]) { 14 p2++; 15 if (p2 > n) { 16 break; 17 } 18 } 19 while (help[p3] * 3 <= help[i]) { 20 p3++; 21 if (p3 > n) { 22 break; 23 } 24 } 25 while (help[p5] * 5 <= help[i]) { 26 p5++; 27 if (p5 > n) { 28 break; 29 } 30 } 31 } 32 return help[n - 1]; 33 }
     1 public int getKthMagicNumber(int k) {
     2         int p3 = 0;
     3         int p5 = 0;
     4         int p7 = 0;
     5         int[] ugly = new int[k + 1];
     6         ugly[0] = 1;
     7         for (int i = 1; i < k; i++) {
     8             ugly[i] = Math.min(3 * ugly[p3], Math.min(5 * ugly[p5],7 * ugly[p7]));
     9             if (ugly[i] == 3 * ugly[p3]) {
    10                 p3++;
    11             }
    12             if (ugly[i] == 5 * ugly[p5]) {
    13                 p5++;
    14             }
    15             if (ugly[i] == 7 * ugly[p7]) {
    16                 p7++;
    17             }
    18         }
    19         return ugly[k-1];
    20     }
  • 相关阅读:
    贪心法
    div 样式
    echarts标题(title)配置
    利用svg画路径图 vue
    vue 杂项
    Charset 0x0408D00000/MS936 is not supported by the JVM
    Android开发中Eclipse常用快捷键
    Java 中强制删除文件的方法
    利用html5的localStorage结合jquery实现日常费用查询器
    Ant编译utf8非法字符:/65279 解决方法
  • 原文地址:https://www.cnblogs.com/isnotnull/p/15124029.html
Copyright © 2020-2023  润新知