• Java---刷题02


    1、数组转字符串

    实现一个方法 toString, 把一个整型数组转换成字符串. 例如数组 {1, 2, 3} , 返回的字符串为 "[1, 2, 3]", 注意 逗号 的位置和数量

    2、118. 杨辉三角 - 力扣(LeetCode)

    3、27. 移除元素 - 力扣(LeetCode)

    4、26. 删除有序数组中的重复项 - 力扣(LeetCode)

    5、88. 合并两个有序数组 - 力扣(LeetCode)

    6、实现 ArrayList 类

    1. public class MyArraylist {
    2. public int[] elem;
    3. public int usedSize;//0
    4. //默认容量
    5. private static final int DEFAULT_SIZE = 10;
    6. public MyArraylist() {
    7. this.elem = new int[DEFAULT_SIZE];
    8. }
    9. /**
    10. * 打印顺序表:
    11. * 根据usedSize判断即可
    12. */
    13. public void display() {
    14. }
    15. // 新增元素,默认在数组最后新增
    16. public void add(int data) {
    17. }
    18. /**
    19. * 判断当前的顺序表是不是满的!
    20. * @return true:满 false代表空
    21. */
    22. public boolean isFull() {
    23. }
    24. private boolean checkPosInAdd(int pos) {
    25. return true;//合法
    26. }
    27. // 在 pos 位置新增元素
    28. public void add(int pos, int data) {
    29. }
    30. // 判定是否包含某个元素
    31. public boolean contains(int toFind) {
    32. return false;
    33. }
    34. // 查找某个元素对应的位置
    35. public int indexOf(int toFind) {
    36. return -1;
    37. }
    38. // 获取 pos 位置的元素
    39. public int get(int pos) {
    40. }
    41. private boolean isEmpty() {
    42. }
    43. // 给 pos 位置的元素设为【更新为】 value
    44. public void set(int pos, int value) {
    45. }
    46. /**
    47. * 删除第一次出现的关键字key
    48. * @param key
    49. */
    50. public void remove(int key) {
    51. }
    52. // 获取顺序表长度
    53. public int size() {
    54. }
    55. // 清空顺序表
    56. public void clear() {
    57. }
    1. public class MyArraylist {
    2. public int[] elem;
    3. public int usedSize;//0
    4. //默认容量
    5. private static final int DEFAULT_SIZE = 10;
    6. public MyArraylist() {
    7. this.elem = new int[DEFAULT_SIZE];
    8. }
    9. /**
    10. * 打印顺序表:
    11. * 根据usedSize判断即可
    12. */
    13. public void display() {
    14. //usedSize==0
    15. for (int i = 0; i < this.usedSize; i++) {
    16. System.out.print(this.elem[i]+" ");
    17. }
    18. System.out.println();
    19. }
    20. // 新增元素,默认在数组最后新增
    21. public void add(int data) {
    22. //1、判断是否是满的,如果满的,那么进行扩容
    23. if(isFull()) {
    24. //扩容
    25. this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
    26. }
    27. //2、不满进行插入
    28. this.elem[this.usedSize] = data;
    29. this.usedSize++;
    30. }
    31. /**
    32. * 判断当前的顺序表是不是满的!
    33. * @return true:满 false代表空
    34. */
    35. public boolean isFull() {
    36. /*if(this.usedSize == this.elem.length) {
    37. return true;
    38. }
    39. return false;*/
    40. return this.usedSize == this.elem.length;
    41. }
    42. private boolean checkPosInAdd(int pos) {
    43. if(pos < 0 || pos > this.usedSize) {
    44. System.out.println("pos位置不合法");
    45. return false;
    46. }
    47. return true;//合法
    48. }
    49. // 在 pos 位置新增元素
    50. public void add(int pos, int data) {
    51. //判断下标是否是合法的
    52. if(!checkPosInAdd(pos)) {
    53. throw new MyArrayListIndexOutOfException("添加方法的pos不合理!");
    54. }
    55. //判断是否是满的
    56. if (isFull()) {
    57. this.elem = Arrays.copyOf(this.elem,2*this.elem.length);
    58. }
    59. //挪数据
    60. for (int i = this.usedSize-1; i >= pos ; i--) {
    61. this.elem[i+1] = this.elem[i];
    62. }
    63. //挪完了数据
    64. this.elem[pos] = data;
    65. this.usedSize++;
    66. }
    67. // 判定是否包含某个元素
    68. public boolean contains(int toFind) {
    69. for (int i = 0; i < this.usedSize; i++) {
    70. if(this.elem[i] == toFind) {
    71. return true;
    72. }
    73. }
    74. return false;
    75. }
    76. // 查找某个元素对应的位置
    77. public int indexOf(int toFind) {
    78. for (int i = 0; i < this.usedSize; i++) {
    79. if(this.elem[i] == toFind) {
    80. return i;
    81. }
    82. }
    83. return -1;
    84. }
    85. private boolean checkPosInGet(int pos) {
    86. if(pos < 0 || pos >= this.usedSize) {
    87. System.out.println("pos位置不合法");
    88. return false;
    89. }
    90. return true;//合法
    91. }
    92. // 获取 pos 位置的元素
    93. public int get(int pos) {
    94. if(!checkPosInGet(pos)) {
    95. throw new MyArrayListIndexOutOfException("获取pos下标时,位置不合法");
    96. }
    97. //不用写判断空不空 没有问题的
    98. if(isEmpty()) {
    99. throw new MyArrayListEmptyException("获取元素的时候,顺序表为空!");
    100. }
    101. return this.elem[pos];
    102. }
    103. private boolean isEmpty() {
    104. return this.usedSize == 0;
    105. }
    106. // 给 pos 位置的元素设为【更新为】 value
    107. public void set(int pos, int value) {
    108. if(!checkPosInGet(pos)){
    109. throw new MyArrayListIndexOutOfException("更新pos下标的元素,位置不合法");
    110. }
    111. //如果合法 ,那么其实不用判断顺序表为空的状态了
    112. if(isEmpty()) {
    113. throw new MyArrayListEmptyException("顺序表为空!");
    114. }
    115. //顺序表为满的情况也可以更新
    116. this.elem[pos] = value;
    117. }
    118. /**
    119. * 删除第一次出现的关键字key
    120. * @param key
    121. */
    122. public void remove(int key) {
    123. if(isEmpty()) {
    124. throw new MyArrayListEmptyException("顺序表为空,不能删除!");
    125. }
    126. int index = indexOf(key);
    127. if(index == -1) {
    128. System.out.println("不存在你要删除的数据");
    129. return;
    130. }
    131. for (int i = index; i < this.usedSize-1; i++) {
    132. this.elem[i] = this.elem[i+1];
    133. }
    134. //删除完成
    135. this.usedSize--;
    136. // this.elem[usedSize] = null; 如果是引用类型 这里需要置为空
    137. }
    138. // 获取顺序表长度
    139. public int size() {
    140. return this.usedSize;
    141. }
    142. // 清空顺序表
    143. public void clear() {
    144. /*
    145. 如果是引用数据类型 得一个一个置为空 这样做才是最合适的
    146. for (int i = 0; i < this.usedSize; i++) {
    147. this.elem[i] = null;
    148. }
    149. this.usedSize = 0;
    150. */
    151. this.usedSize = 0;
    152. }

    7、实现无头单链表的基本操作

    1. // 1、无头单向非循环链表实现
    2. public class SingleLinkedList {
    3. //头插法
    4. public void addFirst(int data);
    5. //尾插法
    6. public void addLast(int data);
    7. //任意位置插入,第一个数据节点为0号下标
    8. public boolean addIndex(int index,int data);
    9. //查找是否包含关键字key是否在单链表当中
    10. public boolean contains(int key);
    11. //删除第一次出现关键字为key的节点
    12. public void remove(int key);
    13. //删除所有值为key的节点
    14. public void removeAllKey(int key);
    15. //得到单链表的长度
    16. public int size();
    17. public void display();
    18. public void clear();
    19. }

    1. public class SingleLinkedList{
    2. static class ListNode {
    3. public int val;//数值域public ListNode next;//存储下一个节点的地址
    4. public ListNode(int val) {
    5. this.val = val;
    6. }
    7. }
    8. public ListNode head;//代表单链表的头结点的引用
    9. /**
    10. * 这里只是简单的进行,链表的构造。
    11. */public void createList() {
    12. ListNode listNode1 = new ListNode(12);
    13. ListNode listNode2 = new ListNode(23);
    14. ListNode listNode3 = new ListNode(34);
    15. ListNode listNode4 = new ListNode(45);
    16. ListNode listNode5 = new ListNode(56);
    17. listNode1.next = listNode2;
    18. listNode2.next = listNode3;
    19. listNode3.next = listNode4;
    20. listNode4.next = listNode5;
    21. this.head = listNode1;
    22. }
    23. public void display() {
    24. ListNode cur = head;
    25. while (cur != null) {
    26. System.out.print(cur.val+" ");
    27. cur = cur.next;
    28. }
    29. System.out.println();
    30. }
    31. /**
    32. * 从指定的节点开始答应
    33. * @param newHead
    34. */public void display(ListNode newHead) {
    35. ListNode cur = newHead;
    36. while (cur != null) {
    37. System.out.print(cur.val+" ");
    38. cur = cur.next;
    39. }
    40. System.out.println();
    41. }
    42. /**
    43. * 头插法
    44. * OaddLast
    45. */public void addFirst(int data){
    46. ListNode node = new ListNode(data);
    47. /*if(this.head == null) {
    48. this.head = node;
    49. }else {
    50. node.next = this.head;
    51. this.head = node;
    52. }*/
    53. node.next = this.head;
    54. this.head = node;
    55. }
    56. //尾插法 O(n)public void addLast(int data) {
    57. ListNode node = new ListNode(data);
    58. if(head == null) {
    59. head = node;
    60. }else {
    61. ListNode cur = head;
    62. while (cur.next != null) {
    63. cur = cur.next;
    64. }
    65. //cur.next == null;
    66. cur.next = node;
    67. }
    68. }
    69. /**
    70. * 任意位置插入,第一个数据节点为0号下标
    71. * 指定位置插入
    72. */
    73. public void addIndex(int index,int data) throws MySingleListIndexOutOfException{
    74. checkIndexAdd(index);
    75. if(index == 0) {
    76. addFirst(data);
    77. return;
    78. }
    79. if(index == size()) {
    80. addLast(data);
    81. return;
    82. }
    83. ListNode node = new ListNode(data);
    84. ListNode cur = findIndexSubOne(index);
    85. node.next = cur.next;
    86. cur.next = node;
    87. }
    88. /**
    89. * 找到index-1位置的节点
    90. * @param index
    91. * @return 该节点的地址
    92. */private ListNode findIndexSubOne(int index) {
    93. ListNode cur = this.head;
    94. while (index-1 != 0) {
    95. cur = cur.next;
    96. index--;
    97. }
    98. return cur;
    99. }
    100. private void checkIndexAdd(int index) {
    101. if(index < 0 || index > size()) {
    102. throw new MySingleListIndexOutOfException("任意位置插入的时候,index不合法!");
    103. }
    104. }
    105. //查找是否包含关键字key是否在单链表当中 314public boolean contains(int key) {
    106. //head == null
    107. ListNode cur = this.head;
    108. //cur != null 说明 没有遍历完 链表while (cur != null) {
    109. if(cur.val == key) {
    110. return true;
    111. }
    112. cur = cur.next;
    113. }
    114. return false;
    115. }
    116. //删除第一次出现关键字为key的节点public void remove(int key){
    117. if(this.head == null) {
    118. System.out.println("此时链表为空,不能进行删除!");
    119. return;
    120. }
    121. if(this.head.val == key) {
    122. //判断 第一个节点是不是等于我要删除的节点this.head = this.head.next;
    123. return;
    124. }
    125. ListNode cur = this.head;
    126. while (cur.next != null) {
    127. if(cur.next.val == key) {
    128. //进行删除了
    129. ListNode del = cur.next;
    130. cur.next = del.next;
    131. return;
    132. }
    133. cur = cur.next;
    134. }
    135. }
    136. //删除所有值为key的节点public void removeAllKey(int key){
    137. if(this.head == null) {
    138. return;
    139. }
    140. ListNode cur = this.head.next;
    141. ListNode prev = this.head;
    142. while (cur != null) {
    143. if(cur.val == key) {
    144. prev.next = cur.next;
    145. cur = cur.next;
    146. }else {
    147. prev = cur;
    148. cur = cur.next;
    149. }
    150. }
    151. //单独处理了头节点if(this.head.val == key) {
    152. head = head.next;
    153. }
    154. }
    155. //得到单链表的长度public int size(){
    156. int count = 0;
    157. ListNode cur = this.head;
    158. while (cur != null) {
    159. count++;
    160. cur = cur.next;
    161. }
    162. return count;
    163. }
    164. /**
    165. * 当我们 执行clear这个函数的时候,会将这个链表当中的所有的节点回收
    166. */public void clear(){
    167. //this.head = null;//这种做法 比较粗暴!
    168. ListNode cur = this.head;
    169. ListNode curNext = null;
    170. while (cur != null) {
    171. curNext = cur.next;
    172. cur.next = null;
    173. cur = curNext;
    174. }
    175. head = null;
    176. }
    177. }

    8、203. 移除链表元素 - 力扣(LeetCode)

    9、206. 反转链表 - 力扣(LeetCode)

    10、876. 链表的中间结点 - 力扣(LeetCode)

    11、链表中倒数第k个结点_牛客题霸_牛客网 (nowcoder.com)

    12、模拟实现 LinkedList 类

    1. // 2、无头双向链表实现
    2. public class LinkedList {
    3. //头插法
    4. public void addFirst(int data);
    5. //尾插法
    6. public void addLast(int data);
    7. //任意位置插入,第一个数据节点为0号下标
    8. public boolean addIndex(int index,int data);
    9. //查找是否包含关键字key是否在单链表当中
    10. public boolean contains(int key);
    11. //删除第一次出现关键字为key的节点
    12. public void remove(int key);
    13. //删除所有值为key的节点
    14. public void removeAllKey(int key);
    15. //得到单链表的长度
    16. public int size();
    17. public void display();
    18. public void clear();
    19. }
    1. public class MyLinkedList {
    2. static class ListNode {
    3. public int val;
    4. public ListNode prev;//前驱
    5. public ListNode next;//后继
    6. public ListNode(int val) {
    7. this.val = val;
    8. }
    9. }
    10. public ListNode head;//标记头
    11. public ListNode last;//标记尾巴
    12. MyLinkedList() {
    13. //last = head = new ListNode(-1);
    14. }
    15. public void display(){
    16. ListNode cur = head;
    17. while (cur != null) {
    18. System.out.print(cur.val+" ");
    19. cur = cur.next;
    20. }
    21. System.out.println();
    22. }
    23. //头插法
    24. public void addFirst(int data){
    25. ListNode node = new ListNode(data);
    26. if(head == null) {
    27. head = node;
    28. last = node;
    29. }else {
    30. node.next = head;
    31. head.prev = node;
    32. head = node;
    33. }
    34. }
    35. //尾插法
    36. public void addLast(int data){
    37. ListNode node = new ListNode(data);
    38. if(head == null) {
    39. head = node;
    40. last = node;
    41. }else {
    42. last.next = node;
    43. node.prev = last;
    44. last = node;
    45. }
    46. }
    47. //任意位置插入,第一个数据节点为0号下标
    48. public void addIndex(int index,int data){
    49. if(index < 0 || index > size()) {
    50. System.out.println("index不合法!");
    51. return;
    52. }
    53. if(index == 0) {
    54. addFirst(data);
    55. return;
    56. }
    57. if(index == size()) {
    58. addLast(data);
    59. return;
    60. }
    61. //cur拿到了index下标的节点的地址
    62. ListNode cur = searchIndex(index);
    63. ListNode node = new ListNode(data);
    64. node.next = cur;
    65. cur.prev.next = node;
    66. node.prev = cur.prev;
    67. cur.prev = node;
    68. }
    69. private ListNode searchIndex(int index) {
    70. ListNode cur = head;
    71. while (index != 0) {
    72. cur = cur.next;
    73. index--;
    74. }
    75. return cur;
    76. }
    77. //查找是否包含关键字key是否在单链表当中
    78. public boolean contains(int key){
    79. ListNode cur = head;
    80. while (cur != null) {
    81. if(cur.val == key) {
    82. return true;
    83. }
    84. cur = cur.next;
    85. }
    86. return false;
    87. }
    88. //删除第一次出现关键字为key的节点
    89. public void remove(int key){
    90. ListNode cur = head;
    91. while (cur != null) {
    92. if(cur.val == key) {
    93. //判断当前是不是头节点
    94. if(cur == head) {
    95. head = head.next;
    96. if(head != null) {
    97. head.prev = null;//这里有问题!!!! 一个节点!
    98. }
    99. }else {
    100. //中间和尾巴的情况
    101. cur.prev.next = cur.next;
    102. if(cur.next != null) {
    103. cur.next.prev = cur.prev;
    104. }else {
    105. last = last.prev;
    106. }
    107. }
    108. return;//删完走人
    109. }else {
    110. cur = cur.next;
    111. }
    112. }
    113. }
    114. //删除所有值为key的节点 之遍历链表一遍
    115. public void removeAllKey(int key){
    116. ListNode cur = head;
    117. while (cur != null) {
    118. if(cur.val == key) {
    119. //判断当前是不是头节点
    120. if(cur == head) {
    121. head = head.next;
    122. if(head != null) {
    123. head.prev = null;//这里有问题!!!! 一个节点!
    124. }
    125. }else {
    126. //中间和尾巴的情况
    127. cur.prev.next = cur.next;
    128. if(cur.next != null) {
    129. cur.next.prev = cur.prev;
    130. }else {
    131. last = last.prev;
    132. }
    133. }
    134. cur = cur.next;
    135. }else {
    136. cur = cur.next;
    137. }
    138. }
    139. }
    140. //得到单链表的长度
    141. public int size(){
    142. int count = 0;
    143. ListNode cur = head;
    144. while (cur != null) {
    145. count++;
    146. cur = cur.next;
    147. }
    148. return count;
    149. }
    150. public void clear(){
    151. ListNode cur = head;
    152. while (cur != null) {
    153. ListNode curNext = cur.next;
    154. ///cur.val = null;
    155. cur.prev = null;
    156. cur.next = null;
    157. cur = curNext;
    158. }
    159. head = null;
    160. last = null;
    161. }
    162. }

    13、141. 环形链表 - 力扣(LeetCode)

    14、142. 环形链表 II - 力扣(LeetCode)

    15、160. 相交链表 - 力扣(LeetCode)

    16、链表的回文结构_牛客题霸_牛客网 (nowcoder.com)

    17、链表分割_牛客题霸_牛客网 (nowcoder.com)

    18、21. 合并两个有序链表 - 力扣(LeetCode)

    19、20. 有效的括号 - 力扣(LeetCode)

    20、栈的压入、弹出序列_牛客题霸_牛客网 (nowcoder.com)

    21、150. 逆波兰表达式求值 - 力扣(LeetCode)

    22、最小栈 - 最小栈 - 力扣(LeetCode)

    23、225. 用队列实现栈 题解 - 力扣(LeetCode)

    24、232. 用栈实现队列 - 力扣(LeetCode)

    25、622. 设计循环队列 - 力扣(LeetCode)

    26、实现二叉树的基本操作

    1. public class BinaryTree {
    2. static class TreeNode {
    3. public char val;
    4. public TreeNode left;//左孩子的引用
    5. public TreeNode right;//右孩子的引用
    6. public TreeNode(char val) {
    7. this.val = val;
    8. }
    9. }
    10. /**
    11. * 创建一棵二叉树 返回这棵树的根节点
    12. *
    13. * @return
    14. */
    15. public TreeNode createTree() {
    16. }
    17. // 前序遍历
    18. public void preOrder(TreeNode root) {
    19. }
    20. // 中序遍历
    21. void inOrder(TreeNode root) {
    22. }
    23. // 后序遍历
    24. void postOrder(TreeNode root) {
    25. }
    26. public static int nodeSize;
    27. /**
    28. * 获取树中节点的个数:遍历思路
    29. */
    30. void size(TreeNode root) {
    31. }
    32. /**
    33. * 获取节点的个数:子问题的思路
    34. *
    35. * @param root
    36. * @return
    37. */
    38. int size2(TreeNode root) {
    39. }
    40. /*
    41. 获取叶子节点的个数:遍历思路
    42. */
    43. public static int leafSize = 0;
    44. void getLeafNodeCount1(TreeNode root) {
    45. }
    46. /*
    47. 获取叶子节点的个数:子问题
    48. */
    49. int getLeafNodeCount2(TreeNode root) {
    50. }
    51. /*
    52. 获取第K层节点的个数
    53. */
    54. int getKLevelNodeCount(TreeNode root, int k) {
    55. }
    56. /*
    57. 获取二叉树的高度
    58. 时间复杂度:O(N)
    59. */
    60. int getHeight(TreeNode root) {
    61. }
    62. // 检测值为value的元素是否存在
    63. TreeNode find(TreeNode root, char val) {
    64. return null;
    65. }
    66. //层序遍历
    67. void levelOrder(TreeNode root) {
    68. }
    69. // 判断一棵树是不是完全二叉树
    70. boolean isCompleteTree(TreeNode root) {
    71. return true;
    72. }
    73. }
    1. public class BinaryTree {
    2. static class TreeNode {
    3. public char val;
    4. public TreeNode left;//左孩子的引用
    5. public TreeNode right;//右孩子的引用
    6. public TreeNode(char val) {
    7. this.val = val;
    8. }
    9. }
    10. /**
    11. * 创建一棵二叉树 返回这棵树的根节点
    12. * 暂且使用穷举的方式创建二叉树
    13. * @return
    14. */
    15. public TreeNode createTree() {
    16. TreeNode A = new TreeNode('A');
    17. TreeNode B = new TreeNode('B');
    18. TreeNode C = new TreeNode('C');
    19. TreeNode D = new TreeNode('D');
    20. TreeNode E = new TreeNode('E');
    21. TreeNode F = new TreeNode('F');
    22. TreeNode G = new TreeNode('G');
    23. TreeNode H = new TreeNode('H');
    24. A.left = B;
    25. A.right = C;
    26. B.left = D;
    27. B.right = E;
    28. C.left = F;
    29. C.right = G;
    30. //E.right = H;
    31. return A;
    32. }
    33. // 前序遍历
    34. public void preOrder(TreeNode root) {
    35. if (root == null) return;
    36. System.out.print(root.val + " ");
    37. preOrder(root.left);
    38. preOrder(root.right);
    39. }
    40. // 中序遍历
    41. void inOrder(TreeNode root) {
    42. if (root == null) return;
    43. inOrder(root.left);
    44. System.out.print(root.val + " ");
    45. inOrder(root.right);
    46. }
    47. // 后序遍历
    48. void postOrder(TreeNode root) {
    49. if (root == null) return;
    50. postOrder(root.left);
    51. postOrder(root.right);
    52. System.out.print(root.val + " ");
    53. }
    54. public static int nodeSize;
    55. /**
    56. * 获取树中节点的个数:遍历思路
    57. */
    58. void size(TreeNode root) {
    59. if (root == null) return;
    60. nodeSize++;
    61. size(root.left);
    62. size(root.right);
    63. }
    64. /**
    65. * 获取节点的个数:子问题的思路
    66. *
    67. * @param root
    68. * @return
    69. */int size2(TreeNode root) {
    70. if (root == null) return 0;
    71. return size2(root.left)
    72. + size2(root.right) + 1;
    73. }
    74. /*
    75. 获取叶子节点的个数:遍历思路
    76. */
    77. public static int leafSize = 0;
    78. void getLeafNodeCount1(TreeNode root) {
    79. if (root == null) return;
    80. if (root.left == null && root.right == null) {
    81. leafSize++;
    82. }
    83. getLeafNodeCount1(root.left);
    84. getLeafNodeCount1(root.right);
    85. }
    86. /*
    87. 获取叶子节点的个数:子问题
    88. */int getLeafNodeCount2(TreeNode root) {
    89. if (root == null) return 0;
    90. if (root.left == null && root.right == null) {
    91. return 1;
    92. }
    93. return getLeafNodeCount2(root.left) + getLeafNodeCount2(root.right);
    94. }
    95. /*
    96. 获取第K层节点的个数
    97. */int getKLevelNodeCount(TreeNode root, int k) {
    98. if (root == null) return 0;
    99. if (k == 1) return 1;
    100. return getKLevelNodeCount(root.left, k - 1) +
    101. getKLevelNodeCount(root.right, k - 1);
    102. }
    103. /*
    104. 获取二叉树的高度
    105. 时间复杂度:O(N)
    106. */int getHeight(TreeNode root) {
    107. if (root == null) return 0;
    108. int leftH = getHeight(root.left);
    109. int rightH = getHeight(root.right);
    110. return leftH > rightH ? leftH + 1 : rightH + 1;
    111. }
    112. // 检测值为value的元素是否存在
    113. TreeNode find(TreeNode root, char val) {
    114. if (root == null) return null;
    115. if (root.val == val) return root;
    116. TreeNode ret = find(root.left, val);
    117. if (ret != null) {
    118. return ret;
    119. }
    120. ret = find(root.right, val);
    121. if (ret != null) {
    122. return ret;
    123. }
    124. return null;
    125. }
    126. //层序遍历
    127. void levelOrder(TreeNode root) {
    128. if (root == null) return;
    129. Queue queue = new LinkedList<>();
    130. queue.offer(root);
    131. while (!queue.isEmpty()) {
    132. TreeNode cur = queue.poll();
    133. System.out.print(cur.val + " ");
    134. if (cur.left != null) {
    135. queue.offer(cur.left);
    136. }
    137. if (cur.right != null) {
    138. queue.offer(cur.right);
    139. }
    140. }
    141. }
    142. // 判断一棵树是不是完全二叉树
    143. boolean isCompleteTree(TreeNode root) {
    144. if (root == null) return false;
    145. Queue queue = new LinkedList<>();
    146. queue.offer(root);
    147. while (!queue.isEmpty()) {
    148. TreeNode cur = queue.poll();
    149. if (cur != null) {
    150. queue.offer(cur.left);
    151. queue.offer(cur.right);
    152. } else {
    153. break;
    154. }
    155. }
    156. //第2次遍历队列 判断队列当中 是否存在非空的元素while (!queue.isEmpty()) {
    157. TreeNode cur = queue.peek();
    158. if (cur == null) {
    159. queue.poll();
    160. } else {
    161. return false;
    162. }
    163. }
    164. return true;
    165. }
    166. }

    27、二叉树遍历_牛客题霸_牛客网 (nowcoder.com)

    28、110. 平衡二叉树 - 力扣(LeetCode)

    29、572. 另一棵树的子树 - 力扣(LeetCode)

    30、101. 对称二叉树 - 力扣(LeetCode)

    31、100. 相同的树 - 力扣(LeetCode)

    32、226. 翻转二叉树 - 力扣(LeetCode)

    33、144. 二叉树的前序遍历 - 力扣(LeetCode)

    34、106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode)

    35、105. 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)

    36、236. 二叉树的最近公共祖先 - 力扣(LeetCode)

    37、107. 二叉树的层序遍历 II - 力扣(LeetCode)

    38、102. 二叉树的层序遍历 - 力扣(LeetCode)

    39、面试题 17.14. 最小K个数 - 力扣(LeetCode)

    40、优先级队列(堆)的模拟实现

    1. public class PriorityQueue {
    2. public int[] elem;
    3. public int usedSize;
    4. public PriorityQueue() {
    5. }
    6. /**
    7. * 建堆的时间复杂度:
    8. *
    9. * @param array
    10. */
    11. public void createHeap(int[] array) {
    12. }
    13. /**
    14. *
    15. * @param root 是每棵子树的根节点的下标
    16. * @param len 是每棵子树调整结束的结束条件
    17. * 向下调整的时间复杂度:O(logn)
    18. */
    19. private void shiftDown(int root,int len) {
    20. }
    21. /**
    22. * 入队:仍然要保持是大根堆
    23. * @param val
    24. */
    25. public void push(int val) {
    26. }
    27. private void shiftUp(int child) {
    28. }
    29. public boolean isFull() {
    30. }
    31. /**
    32. * 出队【删除】:每次删除的都是优先级高的元素
    33. * 仍然要保持是大根堆
    34. */
    35. public void pollHeap() {
    36. }
    37. public boolean isEmpty() {
    38. }
    39. /**
    40. * 获取堆顶元素
    41. * @return
    42. */
    43. public int peekHeap() {
    44. }
    45. }
    1. public class PriorityQueue {
    2. public int[] elem;
    3. public int usedSize;
    4. public PriorityQueue() {
    5. this.elem = new int[10];
    6. }
    7. /**
    8. * 建堆的时间复杂度:
    9. *
    10. * @param array
    11. */
    12. public void createHeap(int[] array) {
    13. //这一步不算是必须的。这里只是我们准备数据,不算做我的建堆时间复杂度当中
    14. for (int i = 0; i < array.length; i++) {
    15. elem[i] = array[i];
    16. usedSize++;
    17. }
    18. for (int p = (usedSize-1-1)/2; p >= 0 ; p--) {
    19. shiftDown(p,usedSize);
    20. }
    21. }
    22. /**
    23. *
    24. * @param root 是每棵子树的根节点的下标
    25. * @param len 是每棵子树调整结束的结束条件
    26. * 向下调整的时间复杂度:O(logn)
    27. */
    28. private void shiftDown(int root,int len) {
    29. int parent = root;
    30. int child = 2*parent+1;
    31. //进入这个循环,说明一定至少有一个孩子
    32. while (child < len) {
    33. //如果有孩子,找到左右孩子的最大值
    34. if(child+1 < len && elem[child] < elem[child+1]) {
    35. child++;
    36. }
    37. //child下标一定保存的是左右孩子最大值的下标
    38. //接下来,孩子的最大值和根节点去比较大小
    39. if(elem[child] > elem[parent]) {
    40. int tmp = elem[child];
    41. elem[child] = elem[parent];
    42. elem[parent] = tmp;
    43. parent = child;//开始更新下标,继续看下面的子树是不是大根堆
    44. child = 2*parent+1;
    45. }else {
    46. break;//此时说明已经是大根堆,不需要进行再次调整了
    47. }
    48. }
    49. }
    50. /**
    51. * 入队:仍然要保持是大根堆
    52. * @param val
    53. */
    54. public void push(int val) {
    55. if(isFull()) {
    56. elem = Arrays.copyOf(elem,2*elem.length);
    57. }
    58. //1、放到最后的位置
    59. elem[usedSize] = val;
    60. //2、进行向上调整
    61. shiftUp(usedSize);
    62. //3、有效数据+1
    63. usedSize++;
    64. }
    65. private void shiftUp(int child) {
    66. int parent = (child-1) / 2;
    67. while (child > 0) {
    68. if(elem[child] > elem[parent]) {
    69. int tmp = elem[child];
    70. elem[child] = elem[parent];
    71. elem[parent] = tmp;
    72. child = parent;
    73. parent = (child-1)/2;
    74. }else {
    75. break;
    76. }
    77. }
    78. }
    79. public boolean isFull() {
    80. return usedSize == elem.length;
    81. }
    82. /**
    83. * 出队【删除】:每次删除的都是优先级高的元素
    84. * 仍然要保持是大根堆
    85. */
    86. public void pollHeap() {
    87. if(isEmpty()) {
    88. System.out.println("优先级队列为空!");
    89. return;
    90. }
    91. int tmp = elem[0];
    92. elem[0] = elem[usedSize-1];
    93. elem[usedSize-1] = tmp;
    94. usedSize--;//9
    95. shiftDown(0,usedSize);
    96. }
    97. public boolean isEmpty() {
    98. return usedSize == 0;
    99. }
    100. /**
    101. * 获取堆顶元素
    102. * @return
    103. */
    104. public int peekHeap() {
    105. if(isEmpty()) {
    106. System.out.println("优先级队列为空!");
    107. return -1;
    108. }
    109. return elem[0];
    110. }
    111. }

    41、插入排序和希尔排序

    1. //=====================================================
    2. // 插入排序
    3. public static void insertSort(int[] array){
    4. // 外层循环目的:取到数组中的每个元素
    5. for(int i = 1; i < array.length; ++i){
    6. // 将该元素插入到序列中
    7. // array数组中:[0, i)的元素已经排好了
    8. // i位置的数据是本次要插入的数据---[0,i)
    9. int key = array[i];
    10. int end = i-1;
    11. while(end >= 0 && key < array[end]){
    12. array[end+1] = array[end];
    13. end--;
    14. }
    15. array[end+1] = key;
    16. }
    17. }
    18. //===========================================================
    19. // 希尔排序
    20. public static void shellSort(int[] array){
    21. int gap = array.length;
    22. while(gap > 1){
    23. gap = gap/3+1;
    24. for(int i = gap; i < array.length; ++i){
    25. // 将该元素插入到序列中
    26. // array数组中:[0, i)的元素已经排好了
    27. // i位置的数据是本次要插入的数据---[0,i)
    28. int key = array[i];
    29. int end = i-gap;
    30. while(end >= 0 && key < array[end]){
    31. array[end+gap] = array[end];
    32. end -= gap;
    33. }
    34. array[end+gap] = key;
    35. }
    36. }
    37. }

    42、选择排序和堆排序

    1. //============================================================
    2. // 选择排序
    3. // 时间复杂度:O(N^2)
    4. // 空间复杂度:O(1)
    5. // 稳定性:不稳定
    6. public static void selectSort(int[] array){
    7. int size = array.length;
    8. for(int i = 0; i < size-1; ++i){ // 控制具体选择的趟数// 具体选择的方式
    9. int pos = 0;
    10. // 找最大元素的位置
    11. for(int j = 0; j < size-i; ++j){
    12. if(array[j] > array[pos]){
    13. pos = j;
    14. }
    15. }
    16. // 用pos标记的最大元素与区间最后一个位置上的元素交换
    17. if(pos != size-1-i){
    18. swap(array, pos, size-i-1);
    19. }
    20. }
    21. }
    22. public static void selectSortOP(int[] array){
    23. int begin = 0;
    24. int end = array.length-1;
    25. while(begin < end){
    26. // 在[begin, end]区间中找最大和最小元素的位置
    27. // 最大元素的位置使用maxPos标记
    28. // 最小元素的位置使用minPos标记
    29. int minPos = begin;
    30. int maxPos = begin;
    31. int index = begin+1;
    32. while(index <= end){
    33. if(array[index] > array[maxPos]){
    34. maxPos = index;
    35. }
    36. if(array[index] < array[minPos]){
    37. minPos = index;
    38. }
    39. index++;
    40. }
    41. // 在[begin, end]区间中,已经找到了最小与最小元素的位置
    42. if(maxPos != end){
    43. swap(array, maxPos, end);
    44. }
    45. if(minPos == end){
    46. minPos = maxPos;
    47. }
    48. if(minPos != begin){
    49. swap(array, minPos, begin);
    50. }
    51. begin++;
    52. end--;
    53. }
    54. }
    55. //================================================================
    56. // 堆排序
    57. public static void shiftDown(int[] array, int size, int parent){
    58. // child标记parent的左孩子---parent可能有左没有右
    59. int child = parent*2 + 1;
    60. while(child < size){ // 如果循环条件成立:parent的左孩子一定是成立的
    61. // 右孩子存在的情况下,找左右孩子中最大的孩子
    62. if(child+1 < size && array[child+1] > array[child]){
    63. child += 1;
    64. }
    65. // 检测parent是否满足堆的特性
    66. if(array[parent] < array[child]){
    67. swap(array, parent, child);
    68. parent = child;
    69. child = parent*2+1;
    70. }else{
    71. return;
    72. }
    73. }
    74. }
    75. // 时间复杂度:O(NlogN)
    76. // 空间复杂度:O(1)
    77. // 稳定性:不稳定
    78. // 应用场景:需要一个序列中前k个最大||最小 ---- 可能会和其他排序复合起来提高排序的效率
    79. public static void heapSort(int[] array){
    80. // 1. 建堆
    81. // a. 找倒数第一个非叶子节点
    82. int size = array.length;
    83. int lastLeaf = ((size-2)>>>1);
    84. for(int root = lastLeaf; root >= 0; root--){
    85. shiftDown(array, size, root);
    86. }
    87. // 2. 利用堆删除的思想排序
    88. int end = size-1;
    89. while(end > 0){
    90. // 用堆顶元素与堆中最后一个元素交换
    91. swap(array, 0, end);
    92. // 将堆中有效元素个数减少一个
    93. // 将堆顶元素向下调整
    94. shiftDown(array, end,0); // logN
    95. end--;
    96. }
    97. }

    43、冒泡排序和快速排序

    1. //================================================================
    2. // 冒泡排序
    3. // 时间复杂度:O(N^2)
    4. // 空间复杂度:O(1)
    5. // 稳定性:稳定
    6. // 应用场景:
    7. public static void bubbleSort(int[] array){
    8. int size = array.length;
    9. for(int i = 0; i < size; ++i){ // 控制冒泡的趟数
    10. boolean isChange = false;
    11. // 具体冒泡的方式:用相邻的两个元素进行交换// 如果不满足条件则交换for(int j = 1; j < size - i; j++){
    12. if(array[j-1] > array[j]){
    13. swap(array, j-1, j);
    14. isChange = true;
    15. }
    16. }
    17. if(!isChange){
    18. return;
    19. }
    20. }
    21. }
    22. //============================================================
    23. // 快速排序
    24. // 三数取中法:
    25. public static int getIndexOfMiddle(int[] array, int left, int right){
    26. // left
    27. // mid: left + ((right-left)>>1)
    28. // right-1
    29. int mid = left + ((right-left)>>1);
    30. if(array[left] < array[right-1]){
    31. if(array[mid] < array[left]){
    32. return left;
    33. }else if(array[mid] > array[right-1]){
    34. return right-1;
    35. }else{
    36. return mid;
    37. }
    38. }else{
    39. if(array[mid] > array[left]){
    40. return left;
    41. }else if(array[mid] < array[right-1]){
    42. return right-1;
    43. }else{
    44. return mid;
    45. }
    46. }
    47. }
    48. // Hoare法时间复杂度:O(N)
    49. public static int partition1(int[] array, int left, int right){
    50. int index = getIndexOfMiddle(array, left, right);
    51. if(index != right-1){
    52. swap(array, index, right-1);
    53. }
    54. int key = array[right-1];
    55. int begin = left;
    56. int end = right-1;
    57. while(begin < end){
    58. // 让begin从前往后找比key大的元素,找到之后停下来
    59. while(begin < end && array[begin] <= key){
    60. begin++;
    61. }
    62. // 让end从后往前找比key小的元素,找到之后停下来
    63. while(begin < end && array[end] >= key){
    64. end--;
    65. }
    66. if(begin != end){
    67. swap(array, begin, end);
    68. }
    69. }
    70. if(begin != right-1){
    71. swap(array, begin, right-1);
    72. }
    73. return begin;
    74. }
    75. // 挖坑法----时间复杂度:O(N)
    76. public static int partition2(int[] array, int left, int right){
    77. int index = getIndexOfMiddle(array, left, right);
    78. if(index != right-1){
    79. swap(array, index, right-1);
    80. }
    81. int key = array[right-1];
    82. int begin = left;
    83. int end = right-1;
    84. while(begin < end){
    85. // 让begin从前往后找比基准值大的元素
    86. while(begin < end && array[begin] <= key){
    87. begin++;
    88. }
    89. if(begin < end){
    90. // begin位置找到了一个比key大的元素,填end位置的坑
    91. array[end] = array[begin];
    92. // begin位置就形成一个新的坑位
    93. }
    94. // 让end从后往前找比基准值小的元素
    95. while(begin < end && array[end] >= key){
    96. end--;
    97. }
    98. if(begin < end){
    99. // end位置找到了一个比key小的元素,填begin位置的坑
    100. array[begin] = array[end];
    101. // end位置就形成了一个新的坑位
    102. }
    103. }
    104. // begin和end位置是最后的一个坑位
    105. // 这个坑位使用基准值填充
    106. array[begin] = key;
    107. return begin;
    108. }
    109. public static int partition(int[] array, int left, int right){
    110. int cur = left;
    111. int prev = cur-1;
    112. int index = getIndexOfMiddle(array, left, right);
    113. if(index != right-1){
    114. swap(array, index, right-1);
    115. }
    116. int key = array[right-1];
    117. // 让cur从前往后找比key小的元素
    118. while(cur < right){
    119. if(array[cur] < key && ++prev != cur){
    120. swap(array, cur, prev);
    121. }
    122. ++cur;
    123. }
    124. // 将基准值的位置放置好
    125. if(++prev != right -1){
    126. swap(array, prev, right-1);
    127. }
    128. return prev;
    129. }
    130. // 时间复杂度:O(NlogN)
    131. // 空间复杂度:O(logN)
    132. // 稳定性:不稳定
    133. // 应用场景:数据越随机越好----越乱越好
    134. public static void insertSortQuick(int[] array, int left, int right){
    135. // 外层循环目的:取到数组中的每个元素
    136. for(int i = left+1; i < right; ++i){
    137. // 将该元素插入到序列中
    138. // array数组中:[0, i)的元素已经排好了
    139. // i位置的数据是本次要插入的数据---[0,i)
    140. int key = array[i];
    141. int end = i-1;
    142. while(end >= 0 && key < array[end]){
    143. array[end+1] = array[end];
    144. end--;
    145. }
    146. array[end+1] = key;
    147. }
    148. }
    149. public static void quickSort(int[] array, int left, int right){
    150. if(right - left < 47) {
    151. insertSortQuick(array, left, right);
    152. }else{
    153. // 假设升序
    154. // 找一个基准值将[left, right)区间分割成两个部分
    155. int div = partition(array, left, right);
    156. // 左侧部分比基准值小
    157. // [left, div)
    158. quickSort(array, left, div);
    159. // 右侧部分比基准值大
    160. // [div+1, right)
    161. quickSort(array, div+1, right);
    162. }
    163. }
    164. public static void quickSort(int[] array){
    165. Stack s = new Stack<>();
    166. s.push(array.length);
    167. s.push(0);
    168. while(!s.empty()){
    169. int left = s.pop();
    170. int right = s.pop();
    171. if(right - left < 47){
    172. insertSortQuick(array, left, right);
    173. }else{
    174. int div = partition2(array, left, right);
    175. // 先压入基准值右侧部分
    176. // [div+1, right);
    177. s.push(right);
    178. s.push(div+1);
    179. // 后压入基准值左侧部分
    180. // [left, div)
    181. s.push(div);
    182. s.push(left);
    183. }
    184. }
    185. }

    44、归并排序和计数排序

    1. //==========================================================
    2. // 归并排序
    3. public static void mergeDate(int[] array, int left, int mid, int right, int[] temp){
    4. int begin1 = left, end1 = mid;
    5. int begin2 = mid, end2 = right;
    6. int index = left;
    7. while(begin1 < end1 && begin2 < end2){
    8. if(array[begin1] <= array[begin2]){
    9. temp[index++] = array[begin1++];
    10. }else{
    11. temp[index++] = array[begin2++];
    12. }
    13. }
    14. while(begin1 < end1){
    15. temp[index++] = array[begin1++];
    16. }
    17. while(begin2 < end2){
    18. temp[index++] = array[begin2++];
    19. }
    20. }
    21. // 时间复杂度:O(NlogN)
    22. // 空间复杂度:O(N)
    23. // 稳定性:稳定
    24. // 应用场景:外部排序
    25. private static void mergeSort(int[] array, int left, int right, int[] temp){
    26. if(right - left > 1){
    27. // 先对[left, right)区间中的元素进行均分
    28. int mid = left + ((right - left)>>1);
    29. // [left, mid)
    30. mergeSort(array, left, mid, temp);
    31. // [mid, right)
    32. mergeSort(array, mid, right, temp);
    33. mergeDate(array, left, mid, right, temp);
    34. System.arraycopy(temp, left, array, left, right-left);
    35. }
    36. }
    37. public static void mergeSort(int[] array){
    38. int[] temp = new int[array.length];
    39. mergeSort(array, 0, array.length, temp);
    40. }
    41. public static void mergeSortNor(int[] array){
    42. int size = array.length;
    43. int[] temp = new int[size];
    44. int gap = 1;
    45. while(gap < size){
    46. for(int i = 0; i < size; i+= 2*gap){
    47. int left = i;
    48. int mid = left + gap;
    49. int right = mid+gap;
    50. if(mid > size){
    51. mid = size;
    52. }
    53. if(right > size){
    54. right = size;
    55. }
    56. mergeDate(array, left, mid, right, temp);
    57. }
    58. System.arraycopy(temp, 0, array, 0, size);
    59. gap <<= 1;
    60. }
    61. }
    62. // 计数排序
    63. //==================================================================
    64. // 时间复杂度:O(N)---N表示数组中元素个数
    65. // 空间复杂度:O(M)---M表示范围的大小
    66. // 稳定性:稳定
    67. // 应用场景:数据密集集中在某个范围中
    68. public static void countSort(int[] array){
    69. // 找数据范围
    70. int maxValue = array[0];
    71. int minValue = array[0];
    72. for(int i = 0; i < array.length; ++i){
    73. if(array[i] > maxValue){
    74. maxValue = array[i];
    75. }
    76. if(array[i] < minValue){
    77. minValue = array[i];
    78. }
    79. }
    80. // 计算计数空间的大小
    81. int range = maxValue - minValue + 1;
    82. int[] count = new int[range];
    83. // 1. 统计array中每个数据出现的次数
    84. for(int i = 0; i < array.length; ++i){
    85. count[array[i] - minValue]++;
    86. }
    87. // 2. 根据统计结果回收
    88. int index = 0;
    89. for(int i = 0; i < range; ++i){
    90. while(count[i] > 0){
    91. array[index++] = i + minValue;
    92. count[i]--;
    93. }
    94. }
    95. }

    45、912. 排序数组 - 力扣(LeetCode)

    46、实现二叉搜索树代码

    1. public class BinarySearchTree {
    2. static class TreeNode {
    3. public int key;
    4. public TreeNode left;
    5. public TreeNode right;
    6. TreeNode(int key) {
    7. this.key = key;
    8. }
    9. }
    10. public TreeNode root;
    11. /**
    12. *
    13. * @param key
    14. */
    15. public boolean insert(int key) {
    16. if(root == null) {
    17. root = new TreeNode(key);
    18. return true;
    19. }
    20. TreeNode cur = root;
    21. TreeNode parent = null;
    22. while (cur != null) {
    23. if(cur.key < key) {
    24. parent = cur;
    25. cur = cur.right;
    26. }else if(cur.key > key) {
    27. parent = cur;
    28. cur = cur.left;
    29. }else {
    30. return false;
    31. }
    32. }
    33. TreeNode node = new TreeNode(key);
    34. //当代码执行到这里之后。cur == null
    35. if(parent.key < key) {
    36. parent.right = node;
    37. }else {
    38. parent.left = node;
    39. }
    40. return true;
    41. }
    42. public TreeNode search(int key) {
    43. TreeNode cur = root;
    44. while (cur != null) {
    45. if(cur.key == key) {
    46. return cur;
    47. }else if(cur.key < key) {
    48. cur = cur.right;
    49. }else {
    50. cur = cur.left;
    51. }
    52. }
    53. return null;
    54. }
    55. public boolean remove(int key) {
    56. TreeNode cur = root;
    57. TreeNode parent = null;
    58. while (cur != null) {
    59. if(cur.key < key) {
    60. parent = cur;
    61. cur = cur.right;
    62. }else if(cur.key == key) {
    63. //这里开始删除!
    64. removeNode(parent,cur);
    65. return true;
    66. }else {
    67. parent = cur;
    68. cur = cur.left;
    69. }
    70. }
    71. return false;
    72. }
    73. private void removeNode(TreeNode parent,TreeNode cur) {
    74. if(cur.left == null) {
    75. if(cur == root) {
    76. root = cur.right;
    77. }else if(cur == parent.left) {
    78. parent.left = cur.right;
    79. }else {
    80. parent.right = cur.right;
    81. }
    82. }else if(cur.right == null) {
    83. if(cur == root) {
    84. root = cur.left;
    85. }else if(cur == parent.left) {
    86. parent.left = cur.left;
    87. }else {
    88. parent.right = cur.left;
    89. }
    90. }else {
    91. TreeNode targetParent = cur;
    92. TreeNode target = cur.right;
    93. while (target.left != null) {
    94. targetParent = target;
    95. target = target.left;
    96. }
    97. cur.key = target.key;
    98. if(target == targetParent.left) {
    99. targetParent.left = target.right;
    100. }else {
    101. targetParent.right = target.right;
    102. }
    103. }
    104. }
    105. //中序遍历即可
    106. public void inorder(TreeNode root) {
    107. if(root == null) return;
    108. inorder(root.left);
    109. System.out.print(root.key+" ");
    110. inorder(root.right);
    111. }
    112. }

    47、二叉搜索树与双向链表_牛客题霸_牛客网 (nowcoder.com)

    48、136. 只出现一次的数字 - 力扣(LeetCode)

    49、771. 宝石与石头 - 力扣(LeetCode)

    50、旧键盘 (20)__牛客网 (nowcoder.com)

  • 相关阅读:
    webpack项目 index.html 根据不同的变量引入不同的js
    HAproxy反向代理与负载均衡
    建模干货:关于ZBrush拓扑的必学技能
    【方向盘】Java EE几十种技术,“活着的”还剩几何(Web应用技术篇)
    第60章 ApplicationPart自动集成整体性和独立性插件项
    5G网络身份ID识别---详解5G-GUTI
    Log4cpp 使用DailyRollingFileAppender 设置按天进行日志轮转
    普通人做自媒体怎么赚钱?
    CAIE ALevel物理(9702)易错题分析
    使用node+vite还有axios发出get请求出现此类问题
  • 原文地址:https://blog.csdn.net/weixin_51912875/article/details/126000936