当前位置: 首页 > news >正文

面试必刷101 Java题解 -- part 1

练习地址

面试必刷101-牛客

    • 1、链表反转
    • 2、链表内指定区间反转
    • **3. 链表中的节点每k个一组翻转**
    • 4、**合并两个排序的链表**
    • 5、**合并k个已排序的链表**
    • 6、**判断链表中是否有环**
    • **7、链表中环的入口结点**
    • 8、链表中倒数最后k个结点
    • **9、删除链表的倒数第n个节点**
    • **10、两个链表的第一个公共结点**
    • **11、链表相加(二)**
    • 12、两数相加
    • 13、字符串相加
    • 14、二进制求和
    • 15、36进制相加
    • **16、单链表的排序**
    • **17、判断一个链表是否为回文结构**
    • **18、判断是否为回文字符串**
    • 19、最长回文字符串
    • **20、链表的奇偶重排**
    • **21、删除有序链表中重复的元素-I**
    • **22、删除有序链表中重复的元素-II**
    • 23、二分查找-I
      • 循环结束条件总结
    • **24、二维数组中的查找**
    • **25、寻找峰值**
    • **24、数组中的逆序对**
    • 25、旋转数组的最小数字
    • 26、比较版本号
    • **27、二叉树的前序遍历**
    • **28、二叉树的中序遍历**
    • 29、二叉树的后序遍历
    • **30、求二叉树的层序遍历**
    • **31、按之字形顺序打印二叉树**
    • 32、二叉树的最大深度
    • **33、二叉树中和为某一值的路径(一)**
    • **34、二叉搜索树与双向链表**
    • 35、**对称的二叉树**
    • **36、合并二叉树**
    • 37、**二叉树的镜像**
    • **38、判断是不是二叉搜索树**
    • **39、判断是不是完全二叉树**
    • **40、判断是不是平衡二叉树**
    • 41、**二叉搜索树的最近公共祖先**
    • **42、在二叉树中找到两个节点的最近公共祖先**
    • **43、序列化二叉树**
    • **44、重建二叉树**
    • **45、输出二叉树的右视图**

1、链表反转

/*
public class ListNode {int val;ListNode next = null;ListNode(int val) {this.val = val;}
}*/
public class Solution {public ListNode ReverseList(ListNode head) {ListNode last = null;ListNode next = null;while(head != null){next = head.next;head.next = last;//反转last = head;//更新装态head = next;}return last;}
}

2、链表内指定区间反转

import java.util.*;public class Solution {public ListNode reverseBetween (ListNode head, int m, int n) {// write code hereListNode dummy = new ListNode(-1);dummy.next = head;ListNode left = dummy;ListNode right = dummy;//走到m的前一个位置for (int i = 0; i < m - 1; i++) {left = left.next;}right = left;ListNode start = left.next;//right要走到n的位置上for (int i = 0; i < n - m + 1; i++) {right = right.next;}ListNode next = right.next;//将n处的next置空right.next = null;left.next = reverse(start);//修正startstart.next = next;return dummy.next;}public ListNode reverse(ListNode head) {ListNode last = null;ListNode next = null;while (head != null) {next = head.next;head.next = last;last = head;head = next;}return last;}
}

3. 链表中的节点每k个一组翻转

public class Solution {/**** @param head ListNode类* @param k int整型* @return ListNode类*/public ListNode reverseKGroup (ListNode head, int k) {// write code hereListNode dummy = new ListNode(-1);dummy.next = head;ListNode left = dummy;ListNode right = dummy;while (right != null) {for (int i = 0; i < k ; i++) {right = right.next;if (right == null) return dummy.next;}ListNode start = left.next;ListNode next = right.next;right.next = null;//指向反转后的结点left.next = myrevser(start);//修正指针错误start.next = next;//重新指向下一个k分组的前一个节点left = start;right = left;}return dummy.next;}public ListNode myrevser(ListNode head) {ListNode last = null;ListNode next = null;while (head != null) {next = head.next;head.next = last;last = head;head = next;}return last;}
}

4、合并两个排序的链表

/*
public class ListNode {int val;ListNode next = null;ListNode(int val) {this.val = val;}
}*/
public class Solution {public ListNode Merge(ListNode list1, ListNode list2) {if (list1 == null) return list2;if (list2 == null) return list1;ListNode help = new ListNode(Integer.MIN_VALUE);ListNode cur = help;while (list1 != null && list2 != null) {if (list1.val <= list2.val) {cur.next = list1;list1 =  list1.next;} else {cur.next = list2;list2 = list2.next;}cur = cur.next;}cur.next = list1 == null ? list2 : list1;return help.next;}
}

5、合并k个已排序的链表

import java.util.*;
/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode(int x) {*         val = x;*         next = null;*     }* }*/
public class Solution {public ListNode mergeKLists(ArrayList<ListNode> lists) {return merger(lists, 0, lists.size() - 1);}public ListNode merger(ArrayList<ListNode> lists, int l, int r) {if (l == r) return lists.get(l);if (l > r) return null;int mid = (l + r) >> 1;ListNode leftmerge = merger(lists, l, mid);ListNode rightmerge = merger(lists, mid + 1, r);return mergerTowList(leftmerge, rightmerge);}public ListNode mergerTowList(ListNode left,ListNode right){if (left == null) return right;if (right == null) return left;ListNode help = new ListNode(Integer.MIN_VALUE);ListNode cur = help;while(left != null && right != null){if(left.val <= right.val){cur.next = left;left = left.next;}else{cur.next = right;right = right.next;}cur = cur.next;}cur.next = left == null ? right : left;return help.next;}
}

6、判断链表中是否有环

public class Solution {public boolean hasCycle(ListNode head) {if(head == null) return false;ListNode fast = head;ListNode slow = head;while(fast != null && fast.next != null){fast = fast.next.next;slow = slow.next;if(slow == fast) return true;}return false;}
}

使用两个指针,fast\textit{fast}fastslow\textit{slow}slow。它们起始都位于链表的头部。随后,slow\textit{slow}slow指针每次向后移动一个位置,而 fast\textit{fast}fast指针向后移动两个位置。如果链表中存在环,则 fast\textit{fast}fast指针最终将再次与 slow\textit{slow}slow指针在环中相遇。

7、链表中环的入口结点

使用两个指针,fast\textit{fast}fastslow\textit{slow}slow。它们起始都位于链表的头部。随后,slow\textit{slow}slow指针每次向后移动一个位置,而 fast\textit{fast}fast指针向后移动两个位置。如果链表中存在环,则 fast\textit{fast}fast指针最终将再次与slow\textit{slow}slow指针在环中相遇。当发现fast\textit{fast}fastslow\textit{slow}slow相遇时,将fast\textit{fast}fast指向链表头部;随后,它和slow\textit{slow}slow每次向后移动一个位置。最终,它们会在入环点相遇。

public class Solution {public ListNode EntryNodeOfLoop(ListNode pHead) {if(pHead == null) return null;ListNode fast = pHead;ListNode slow = pHead;while(fast != null && fast.next != null){fast = fast.next.next;slow = slow.next;if(slow == fast){fast = pHead;while(fast != slow){fast = fast.next;slow = slow.next;}return fast;}}return null;}
}

8、链表中倒数最后k个结点

  • 使用双指针则可以不用统计链表长度。
public ListNode FindKthToTail (ListNode pHead, int k) {// write code hereListNode fast = pHead;ListNode slow = pHead;for (int i = 0; i < k; i++) {if(fast == null) return null;fast = fast.next;}while (fast != null) {fast = fast.next;slow = slow.next;}return slow;}

9、删除链表的倒数第n个节点

public ListNode removeNthFromEnd (ListNode head, int n) {// write code hereListNode dummy = new ListNode(-1);dummy.next = head;ListNode fast = head;ListNode slow = dummy; //将slow位置提前for (int i = 0; i < n ; i++) {//快慢指针,走到第n个节点的前一个fast = fast.next;}while (fast != null) {fast = fast.next;slow = slow.next;}slow.next = slow.next.next;return dummy.next;}

10、两个链表的第一个公共结点

public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {int length  = 0; // pHead1 - pHead2长度之差if (pHead1 == null || pHead2 == null) return null;ListNode cur1 = pHead1;ListNode cur2 = pHead2;while (cur1 != null) {cur1 = cur1.next;length++;}while (cur2 != null) {cur2 = cur2.next;length--;}// 尾端节点不一致判断没有节点if (cur1 != cur2) return null;// cur1表示长的那个链表cur1 = length > 0 ? pHead1 : pHead2;cur2 = cur1 == pHead1 ? pHead2 : pHead1;length = Math.abs(length);// 长链表走length步for (int i = 0; i < length; i++) {cur1 = cur1.next;}// 两个链表同时走直到相遇while (cur1 != cur2) {cur1 = cur1.next;cur2 = cur2.next;}return cur1;}

11、链表相加(二)

本题的主要难点在于链表中数位的顺序与我们做加法的顺序是相反的,为了逆序处理所有数位,我们可以使用栈:把所有数字压入栈中,再依次取出相加。计算过程中需要注意进位的情况。

public ListNode addInList (ListNode head1, ListNode head2) {// write code hereStack<Integer> s1 = new Stack<>();Stack<Integer> s2 = new Stack<>();//将链表中数据放入栈中while (head1 != null) {s1.push(head1.val);head1 = head1.next;}while (head2 != null) {s2.push(head2.val);head2 = head2.next;}ListNode res = null; //返回的结果int carry = 0; //进位// 栈不为空或者存在进位时while (!s1.isEmpty() || !s2.isEmpty() || carry != 0) {int val1 = s1.isEmpty() ? 0 : s1.pop();int val2 = s2.isEmpty() ? 0 : s2.pop();int sum = val1 + val2 + carry;carry = sum / 10; // 更新进位int cur = sum % 10; // 个位数字ListNode curNode = new ListNode(cur);//更新结果并连线curNode.next = res;res = curNode;}return res;}

12、两数相加

本题低位在前高位在后,可以直接从头开始相加

public ListNode addTwoNumbers(ListNode head1, ListNode head2) {// write code hereListNode res = new ListNode(0); //返回的结果ListNode help = res;int carry = 0; //进位// 栈不为空或者存在进位时while (head1!=null || head2!=null || carry != 0) {int val1 = head1==null ? 0 : head1.val;int val2 = head2==null ? 0 : head2.val;int sum = val1 + val2 + carry;carry = sum / 10; // 更新进位int cur = sum % 10; // 个位数字help.next = new ListNode(cur);help = help.next;if(head1!=null) head1 = head1.next;if(head2!=null) head2 = head2.next;}return res.next;}

13、字符串相加

public String addStrings(String num1, String num2) {StringBuilder res = new StringBuilder("");int num1Length = num1.length() - 1;int num2Length = num2.length() - 1;int carry = 0;//进位while (num1Length >= 0 || num2Length >= 0 || carry != 0) {int n1 = num1Length >= 0 ? num1.charAt(num1Length) - '0' : 0;int n2 = num2Length >= 0 ? num2.charAt(num2Length) - '0' : 0;int sum = n1 + n2 + carry;carry = sum / 10; //更新进位int cur = sum % 10; //个位上数字res.append(cur);num1Length--;num2Length--;}return res.reverse().toString();}

14、二进制求和

class Solution {public String addBinary(String a, String b) {StringBuilder ans = new StringBuilder();int alength = a.length() - 1;int blength = b.length() - 1;int carry = 0;//进位while(alength >= 0 || blength >= 0 || carry != 0){int n1 = alength >= 0? a.charAt(alength) - '0':0;int n2 = blength >= 0? b.charAt(blength) - '0':0;int sum = n1 + n2 + carry;int cur = sum % 2;carry = sum / 2; //更新进位ans.append(cur);alength--;blength--;}return ans.reverse().toString();}
}

15、36进制相加

题目

实现一个 36 进制的加法 0-9 a-z。

示例

输入:[“abbbb”,“1”],输出:“abbbc”

String add36Strings(String num1, String num2) {int carry = 0;int i = num1.length() - 1, j = num2.length() - 1;StringBuilder sb = new StringBuilder();while (i >= 0 || j >= 0 || carry != 0) {int x = i >= 0 ? getInt(num1.charAt(i)) : 0;int y = j >= 0 ? getInt(num2.charAt(j)) : 0;int sum = x + y + carry; //本次结果sb.append(getChar(sum % 36));carry = sum / 36; //进位i--;j--;}//翻转return sb.reverse().toString();}private int getInt(char i) {if (i >= '0' && i <= '9') {return i - '0';} else {return i - 'a' + 10;}}private char getChar(int i) {if (i <= 9) {return (char) (i + '0');} else {return (char) (i - 10 + 'a');}}

16、单链表的排序

对于链表最适合的是归并排序

public class Solution {/**** @param head ListNode类 the head node* @return ListNode类*/public ListNode sortInList (ListNode head) {// write code here// 对于链表最适合的是归并排序if(head == null) return null;return sortPartList(head);}public ListNode sortPartList(ListNode head) {if (head.next == null) return head; //链表只有一个节点// 获取 mid -- 中点为slowListNode fast = head, slow = head;ListNode pre = null;//中点的前一个节点while (fast != null && fast.next != null) {pre = slow;slow = slow.next;fast = fast.next.next;}pre.next = null; //断开拆成两个链表ListNode leftNode = sortPartList(head);ListNode rightNode = sortPartList(slow);return merge(leftNode, rightNode);}public ListNode merge(ListNode left, ListNode right) {ListNode dummy = new ListNode(0);ListNode help = dummy;while (left != null && right != null) {if (left.val <= right.val) {help.next = left;left = left.next;} else {help.next = right;right = right.next;}help = help.next;}help.next = left == null ? right : left;return dummy.next;}
}

快速方法

public ListNode sortInList (ListNode head) {// write code here//小根堆Queue<ListNode> queue = new PriorityQueue<>((o1, o2) -> o1.val - o2.val);ListNode help = new ListNode(0);ListNode temp = help;while(head != null){queue.add(head);head = head.next;}while(!queue.isEmpty()){ListNode node = queue.poll();node.next = null;//将节点next置空temp.next = node;temp = temp.next;//更新}return help.next;}

17、判断一个链表是否为回文结构

利用快慢指针找到中点,将后半截反序,两个指针从两边遍历到中点,逐个比较

当慢指针走到中点时,将其下一个指针赋值为null,同时将后面的指针指向中点,然后遍历,返回true/false,然后在将后面的指针改回去

public boolean isPail (ListNode head) {// write code hereListNode fast = head, slow = head;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;}// 中点即为slowslow = reverse(slow);fast = head;while (slow != null) {if (slow.val != fast.val) return false;slow = slow.next;fast = fast.next;}return true;}public ListNode reverse(ListNode head) {ListNode last = null;ListNode next = null;while (head != null) {next = head.next;head.next = last;//reverselast = head;head = next;}return last;}

18、判断是否为回文字符串

import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可** @param str string字符串 待判断的字符串* @return bool布尔型*/public boolean judge (String str) {// write code hereint l = 0;int r = str.length() - 1;while (l < r) {if (str.charAt(l) != str.charAt(r)) return false;l++;r--;}return true;}
}

19、最长回文字符串

  • step 1:遍历字符串每个字符。
  • step 2:以每次遍历到的字符为中心(分奇数长度和偶数长度两种情况),不断向两边扩展。
  • step 3:如果两边都是相同的就是回文,不断扩大到最大长度即是以这个字符(或偶数两个)为中心的最长回文子串。
  • step 4:我们比较完每个字符为中心的最长回文子串,取最大值即可。
import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可*** @param A string字符串* @return int整型*/public int getLongestPalindrome (String A) {// write code hereint res = 1;for (int i = 0; i < A.length() - 1; i++) {//分为奇数和偶数两种情况res = Math.max(res, Math.max(helper(A, i, i), helper(A, i, i + 1)));}return res;}public int helper(String A, int begin, int end) {//每个中心点开始扩展while (begin >= 0 && end < A.length() && A.charAt(begin) == A.charAt(end)) {begin--;end++;}//返回长度return end - begin - 1;}
}

20、链表的奇偶重排

先一个左正蹬,把奇数节点串一块儿,再一个右鞭腿,把偶数节点串一起,然后啪,很快啊,把两个连成一条链表,可以说是训练有素,有bear来了

public ListNode oddEvenList (ListNode head) {// write code hereif(head == null) return head;ListNode odd = head;//奇数ListNode even = head.next, evenHead = even; //偶数while(even != null && even.next != null){odd.next = even.next;odd = odd.next;even.next = odd.next;even = even.next;}odd.next = evenHead;return head;//奇数头是head}

21、删除有序链表中重复的元素-I

import java.util.*;
public class Solution {public ListNode deleteDuplicates (ListNode head) {//一次遍历//空链表if(head == null) return null;//遍历指针ListNode cur = head; //指针当前和下一位不为空while(cur != null && cur.next != null){ //如果当前与下一位相等则忽略下一位if(cur.val == cur.next.val) cur.next = cur.next.next;//否则指针正常遍历else cur = cur.next;}return head;}
}

22、删除有序链表中重复的元素-II

删除重复元素,只要重复就全部给删除(一个也不留)

import java.util.*;
public class Solution {public ListNode deleteDuplicates (ListNode head) {//空链表if(head == null) return null;ListNode dummy = new ListNode(0);//在链表前加一个表头dummy.next = head;ListNode helper = dummy;while(helper.next != null && helper.next.next != null){//遇到相邻两个节点值相同if(helper.next.val == helper.next.next.val){int temp = helper.next.val;//将所有相同的都跳过while (helper.next != null && helper.next.val == temp)helper.next = helper.next.next;//忽略下一位}elsehelper = helper.next;}//返回时去掉表头return dummy.next;}
}

23、二分查找-I

public int search (int[] nums, int target) {// write code hereint left = 0, right = nums.length - 1 ;while (left <= right) {int mid = left  + (right - left) / 2;int num = nums[mid];if (num == target) return mid;else if (num > target) right = mid - 1;else left = mid + 1;}return -1;
}

循环结束条件总结

情况一

如果搜索区间[left, right]中一定有目标值索引,那么循环截止条件是while(left < right)

情况二

如果搜索区间[left, right]中不一定有目标值索引,那么循环截止条件是while(left <= right);(一般用于搜索区间内是否有某个值)

24、二维数组中的查找

首先看四个角,左上与右下必定为最小值与最大值,而左下与右上就有规律了:左下元素大于它上方的元素,小于它右方的元素,右上元素与之相反。既然左下角元素有这么一种规律,相当于将要查找的部分分成了一个大区间和小区间,每次与左下角元素比较,我们就知道目标值应该在哪部分中,于是可以利用分治思维来做。

具体做法:

  • step 1:首先获取矩阵的两个边长,判断特殊情况。
  • step 2:首先以左下角为起点,若是它小于目标元素,则往右移动去找大的,若是他大于目标元素,则往上移动去找小的。
  • step 3:若是移动到了矩阵边界也没找到,说明矩阵中不存在目标值。
public class Solution {public boolean Find(int target, int [][] array) {int r = array.length - 1;int c = 0;while(r >= 0 && c < array[0].length){int cmp = array[r][c];if(cmp == target) return true;else if(cmp > target) r--;else c++;}return false;}
}

25、寻找峰值

public class Solution {public int findPeakElement (int[] nums) {// write code hereint left = 0;int right = nums.length - 1;int mid;while (left < right) {// 找到中间值mid = (left + right) >> 1;// 只要当前中间值 大于它的下一位,说明当前处于下坡状态,那么往数组的左边遍历,就可以找到峰值if(nums[mid] > nums[mid + 1])// 因为mid 比 它下一位大,所以当前mid有可能是山峰,这里向左遍历的时候需要把mid包含在内right = mid; else // 否则当前中间值小于等于它的下一位时,说明山峰处于上坡状态,向右查找就可以找到峰值// 因为mid小于它的下一位,所以这里将left赋值为mid+1,从大的那个数开始向右查找left = mid + 1;}// 此时left 和 right相等时 上面的while退出// 最终返回 left 或 right都可以return right;}
}

24、数组中的逆序对

public class Solution {public int InversePairs(int [] array) {//归并算法//计数条件是左边大于右边if (array == null || array.length < 2) return 0;return (int)process(array, 0, array.length - 1) % 1000000007;}public long process(int [] array, int left, int right) {if (left >= right) return 0;int mid = left + (right - left) / 2;long leftnum = process(array, left, mid);//左边排好序long rightnum = process(array, mid + 1, right);//右边排好序long mergernum = merge(array, left, mid,right); //利用外排序将左右两边排好序return leftnum + rightnum + mergernum;}public long merge(int [] array, int left, int mid, int right) {int[] help = new int[right - left + 1];int helpIndex = 0;//外排索引int count  = 0;//逆序对数量int leftHead = left;//左边头索引int rightHead = mid + 1;//右边头索引while (leftHead <= mid && rightHead <= right) {if (array[leftHead] <= array[rightHead]) {help[helpIndex++] = array[leftHead++];} else {help[helpIndex++] = array[rightHead++];count = count + mid - leftHead + 1;}}while (leftHead <= mid) {help[helpIndex++] = array[leftHead++];}while (rightHead <= right) {help[helpIndex++] = array[rightHead++];}//覆盖回去for (int i = 0; i < help.length; i++) {array[left + i] = help[i];}return count % 1000000007;}
}

25、旋转数组的最小数字

思路:

旋转数组将原本有序的数组分成了两部分有序的数组,因为在原始有序数组中,最小的元素一定是在首位,旋转后无序的点就是最小的数字。我们可以将旋转前的前半段命名为A,旋转后的前半段命名为B,旋转数组即将AB变成了BA,我们想知道最小的元素到底在哪里。

因为A部分和B部分都是各自有序的,所以我们还是想用分治来试试,每次比较中间值,确认目标值(最小元素)所在的区间。

具体做法:

  • step 1:双指针指向旋转后数组的首尾,作为区间端点。
  • step 2:若是区间中点值大于区间右界值,则最小的数字一定在中点右边。
  • step 3:若是区间中点值等于区间右界值,则是不容易分辨最小数字在哪半个区间,比如[1,1,1,0,1],应该逐个缩减右界。
  • step 4:若是区间中点值小于区间右界值,则最小的数字一定在中点左边。
  • step 5:通过调整区间最后即可锁定最小值所在。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aMA7sX5G-1677307640258)(${img}/image-20230112124909276.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b3jz71xM-1677307640258)(${img}/image-20230112125112145.png)]

public int minNumberInRotateArray(int [] array) {int left = 0, right = array.length - 1 ;while (left < right) {int mid = left + (right - left) / 2;//区间中点值大于区间右界值,则最小的数字一定在中点右边。//array[right] 是右边界if (array[mid] > array[right])  left = mid + 1;//区间中点值小于区间右界值,则最小的数字一定在中点左边。else if (array[mid] < array[right]) right = mid;else right--;//无法判断在哪一边 区间中点值等于区间右界值,则是不容易分辨最小数字在哪半个区间,比如[1,1,1,0,1],应该逐个缩减右界。}return array[left];
}

26、比较版本号

具体做法:

  • step 1:利用两个指针表示字符串的下标,分别遍历两个字符串。
  • step 2:每次截取点之前的数字字符组成数字,即在遇到一个点之前,直接取数字,加在前面数字乘10的后面。(因为int会溢出,这里采用long记录数字)
  • step 3:然后比较两个数字大小,根据大小关系返回1或者-1,如果全部比较完都无法比较出大小关系,则返回0.
public int compare (String version1, String version2) {// write code hereint len1 = version1.length(), len2 = version2.length();int n1 = 0, n2 = 0;while (n1 < len1 || n2 < len2) {int num1 = 0, num2 = 0; //每个点间的数字while (n1 < len1 && version1.charAt(n1) != '.') {num1 = num1 * 10 + version1.charAt(n1++) - '0';}while (n2 < len2 && version2.charAt(n2) != '.') {num2 = num2 * 10 + version2.charAt(n2++) - '0';}//判断每个点间的数字大小if (num1 > num2) return 1;else if (num1 < num2) return -1;n1++;n2++;//跳过点}return 0;
}

27、二叉树的前序遍历

//递归方式
public int[] preorderTraversal (TreeNode root) {// write code hereList<Integer> list = new ArrayList<>();preorder(root, list);int[] res = new int[list.size()];for (int i = 0; i < list.size(); i++) {res[i] = list.get(i);}return res;
}
public void preorder(TreeNode node, List<Integer> list) {if (node == null) return;list.add(node.val);preorder(node.left, list);preorder(node.right, list);
}
//非递归方式
public int[] preorderTraversal (TreeNode root) {//添加遍历结果的数组List<Integer> list = new ArrayList();Stack<TreeNode> s = new Stack<TreeNode>();//空树返回空数组if(root == null)return new int[0];//根节点先进栈s.push(root);while(!s.isEmpty()){//每次栈顶就是访问的元素TreeNode node = s.pop();list.add(node.val);//如果右边还有右子节点进栈if(node.right != null)s.push(node.right);//如果左边还有左子节点进栈if(node.left != null)s.push(node.left);}//返回的结果int[] res = new int[list.size()];for(int i = 0; i < list.size(); i++)res[i] = list.get(i);return res;
}

28、二叉树的中序遍历

public int[] inorderTraversal (TreeNode root) {// write code here// 递归方式List<Integer> list = new ArrayList<>();inorder(root, list);int[] res = new int[list.size()];for (int i = 0; i < list.size(); i++) {res[i] = list.get(i);}return res;
}
public void inorder(TreeNode root, List<Integer> list) {if (root == null) return;inorder(root.left, list);list.add(root.val);inorder(root.right, list);
}public int[] inorderTraversal (TreeNode root) {//非递归方式//每棵子树,整棵树左边界依次进栈,依次弹出,处理,对右树循环//添加遍历结果的数组List<Integer> list = new ArrayList(); Stack<TreeNode> s = new Stack<TreeNode>();//空树返回空数组if(root == null) return new int[0];//当树节点不为空或栈中有节点时while(root != null || !s.isEmpty()){ //每次找到最左节点while(root != null){ s.push(root);root = root.left;}//访问该节点TreeNode node = s.pop(); list.add(node.val); //进入右节点root = node.right; }//返回的结果int[] res = new int[list.size()]; for(int i = 0; i < list.size(); i++)res[i] = list.get(i);return res;
}

29、二叉树的后序遍历

public int[] postorderTraversal (TreeNode root) {// write code hereList<Integer> list = new ArrayList<>();postorder(root, list);int[] res = new int[list.size()];for (int i = 0; i < list.size(); i++) {res[i] = list.get(i);}return res;
}
public void postorder(TreeNode root, List<Integer> list) {if (root == null) return;postorder(root.left, list);postorder(root.right, list);list.add(root.val);
}//非递归,头入栈,放入另一个栈,先左后右
public int[] postorderTraversal (TreeNode root) {// write code hereList<Integer> list = new ArrayList<>();Stack<TreeNode> stack1 = new Stack<>();Stack<TreeNode> stack2 = new Stack<>();stack1.push(root);if (root == null) return new int[0];while (!stack1.isEmpty()) {TreeNode node  = stack1.pop();stack2.push(node);if (node.left != null) {stack1.push(node.left);}if (node.right != null) {stack1.push(node.right);}}while (!stack2.isEmpty()) {list.add(stack2.pop().val);}int[] res = new int[list.size()];for (int i = 0; i < list.size(); i++) {res[i] = list.get(i);}return res;
}

30、求二叉树的层序遍历

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MHAsUcY5-1677307640261)(${img}/Untitled 23.png)]

public ArrayList<ArrayList<Integer>> levelOrder (TreeNode root) {// write code hereArrayList<ArrayList<Integer>> array = new ArrayList<>();if (root == null) return array;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while (!queue.isEmpty()) {ArrayList<Integer> temp = new ArrayList<Integer>();int n = queue.size();//该层数量while (n-- > 0) {TreeNode node = queue.poll();temp.add(node.val);if(node.left!=null) queue.offer(node.left);if(node.right!=null) queue.offer(node.right);}array.add(temp);}return array;
}

31、按之字形顺序打印二叉树

public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {ArrayList<ArrayList<Integer>> array = new ArrayList<>();if (pRoot == null) return array;Queue<TreeNode> queue = new LinkedList<>();boolean flag = true;queue.add(pRoot);while (!queue.isEmpty()) {ArrayList<Integer> temp = new ArrayList<Integer>();int n = queue.size();//该层数量while (n-- > 0) {TreeNode node = queue.poll();temp.add(node.val);if (node.left != null) queue.add(node.left);if (node.right != null) queue.add(node.right);}//奇数行反转,偶数行不反转flag = !flag;if (flag)Collections.reverse(temp);array.add(temp);}return array;
}

32、二叉树的最大深度

public int maxDepth (TreeNode root) {// write code here// 递归终止if (root == null) {return 0;}// dfs,先递归左子结点,再递归右子结点,最后求出每一子树的深度的最大值return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}public int maxDepth (TreeNode root) {// write code hereif (root == null) return 0;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);int res = 0;while (!queue.isEmpty()) {int n = queue.size();//该层数量while (n-- > 0) {TreeNode node = queue.poll();if (node.left != null) queue.offer(node.left);if (node.right != null) queue.offer(node.right);}res++;}return res;
}

33、二叉树中和为某一值的路径(一)

遍历的方法我们可以选取二叉树常用的递归前序遍历,因为每次进入一个子节点,更新sum值以后,相当于对子树查找有没有等于新目标值的路径,因此这就是子问题,递归的三段式为:

  • 终止条件: 每当遇到节点为空,意味着过了叶子节点,返回。每当检查到某个节点没有子节点,它就是叶子节点,此时sum减去叶子节点值刚好为0,说明找到了路径。
  • 返回值: 将子问题中是否有符合新目标值的路径层层往上返回。
  • 本级任务: 每一级需要检查是否到了叶子节点,如果没有则递归地进入子节点,同时更新sum值减掉本层的节点值。

具体做法:

  • step 1:每次检查遍历到的节点是否为空节点,空节点就没有路径。
  • step 2:再检查遍历到是否为叶子节点,且当前sum值等于节点值,说明可以刚好找到。
  • step 3:检查左右子节点是否可以有完成路径的,如果任意一条路径可以都返回true,因此这里选用两个子节点递归的或。
public class Solution {public boolean hasPathSum (TreeNode root, int sum) {// write code hereif (root == null) return false;return dfs(root, sum);}public boolean dfs(TreeNode node, int target) {if (node == null) return false;// 目标路径不存在,开始回溯target -= node.val; // 更新目标值 // 当前节点为叶子节点并且目标路径存在时,返回 trueif (node.left == null && node.right == null && target == 0) return true;return dfs(node.left, target) || dfs(node.right, target);}
}

34、二叉搜索树与双向链表

//递归
public class Solution {private TreeNode head = null;//起始位置private TreeNode pre  = null;//不断更新的位置public TreeNode Convert(TreeNode pRootOfTree) {if (pRootOfTree == null) return null;//中序遍历即为有序Convert(pRootOfTree.left);if (head == null) {head = pRootOfTree;//最左端pre = head;} else {pre.right = pRootOfTree;//右指针指向后继pRootOfTree.left = pre;//左指针指向前继pre = pRootOfTree; //更新位置}Convert(pRootOfTree.right);return head;}
}//非递归
public class Solution {public TreeNode Convert(TreeNode pRootOfTree) {if (pRootOfTree == null)return null;//使用非递归方式Stack<TreeNode> s = new Stack<>();TreeNode head = null;TreeNode pre = null;boolean flag = true;while (pRootOfTree != null || !s.isEmpty()) {//直到没有左节点while (pRootOfTree != null) {s.push(pRootOfTree);pRootOfTree = pRootOfTree.left;//更新最左边}TreeNode node = s.pop();//弹出//处理if (flag) {//第一次最左边head = node;pre = head;flag = false;} else {pre.right = node;//右指针指向后继node.left = pre;//左指针指向前继pre = node;//更新}pRootOfTree = node.right;//进入右边}return head;}
}

35、对称的二叉树

遍历方式依据前序递归可以使用递归:

  • 终止条件: 当进入子问题的两个节点都为空,说明都到了叶子节点,且是同步的,因此结束本次子问题,返回true;当进入子问题的两个节点只有一个为空,或是元素值不相等,说明这里的对称不匹配,同样结束本次子问题,返回false。
  • 返回值: 每一级将子问题是否匹配的结果往上传递。
  • 本级任务: 每个子问题,需要按照上述思路,“根左右”走左边的时候“根右左”走右边,“根左右”走右边的时候“根右左”走左边,一起进入子问题,需要两边都是匹配才能对称。

具体做法:

  • step 1:两种方向的前序遍历,同步过程中的当前两个节点,同为空,属于对称的范畴。
  • step 2:当前两个节点只有一个为空或者节点值不相等,已经不是对称的二叉树了。
  • step 3:第一个节点的左子树与第二个节点的右子树同步递归对比,第一个节点的右子树与第二个节点的左子树同步递归比较。
public class Solution {boolean isSymmetrical(TreeNode pRoot) {if(pRoot == null) return true;return recursion(pRoot.left, pRoot.right);}private boolean recursion(TreeNode left, TreeNode right) {if (left == null && right == null) return true;//可以两个都为空if (left == null || right == null || left.val != right.val) return false;//只有一个为空或者节点值不同,必定不对称return recursion(left.left, right.right) && recursion(left.right, right.left);//每层对应的节点进入递归比较}
}
//非递归
public class Solution {boolean isSymmetrical(TreeNode pRoot) {if(pRoot == null) return true;Queue<TreeNode> q1 = new LinkedList<>();//左边子树Queue<TreeNode> q2 = new LinkedList<>();//右边子树q1.offer(pRoot.left);q2.offer(pRoot.right);while(!q1.isEmpty()&&!q2.isEmpty()){TreeNode n1 = q1.poll();//leftNodeTreeNode n2 = q2.poll();//rightNode//判断if(n1 == null && n2 == null) continue;if(n1 == null || n2 == null || n1.val != n2.val) return false;q1.offer(n1.left);q2.offer(n2.right);q1.offer(n1.right);q2.offer(n2.left);}return true;}}

36、合并二叉树

public TreeNode mergeTrees (TreeNode t1, TreeNode t2) {// write code hereif (t1 == null) return t2;if (t2 == null) return t1;TreeNode node = new TreeNode(t1.val + t2.val);node.left = mergeTrees(t1.left, t2.left);node.right = mergeTrees(t1.right, t2.right);return node;
}

37、二叉树的镜像

public TreeNode Mirror (TreeNode pRoot) {// write code here// 先序遍历,从顶向下交换if(pRoot == null) return null;//父问题 交换两个子节点的值。TreeNode temp = pRoot.left;pRoot.left = pRoot.right;pRoot.right = temp;Mirror(pRoot.left);//左子树交换Mirror(pRoot.right);//右子树交换return pRoot;
}

38、判断是不是二叉搜索树

class Solution {long pre = Long.MIN_VALUE; //前一个左子树的值public boolean isValidBST(TreeNode root) {if(root == null) return true;if(!isValidBST(root.left)) return false;if(pre >= root.val) return false;pre = root.val;return isValidBST(root.right);}
}

39、判断是不是完全二叉树

public class Solution {public boolean isCompleteTree (TreeNode root) {// write code here// BFSif(root == null) return true;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);boolean isComplete = true;while(!queue.isEmpty()){TreeNode node = queue.poll();if(node == null){//第一次遇到nullisComplete = false;continue;}//遇到null后不应该再遇到非空节点了if(!isComplete) return false;queue.offer(node.left);queue.offer(node.right);}return true;}
}

40、判断是不是平衡二叉树

public class Solution {public boolean IsBalanced_Solution(TreeNode root) {if (root == null) return true;//父问题:左右两个子树的高度差的绝对值不超过1int left = deep(root.left);int right = deep(root.right);if (Math.abs(left - right) > 1) return false;//子问题:左右两个子树都是一棵平衡二叉树。return IsBalanced_Solution(root.left) && IsBalanced_Solution(root.right);}private int deep(TreeNode node) {if (node == null) return 0;//子问题:左右子树高度int left = deep(node.left);int right = deep(node.right);//父问题:左右子树的最大高度return Math.max(left,right) + 1;}
}

41、二叉搜索树的最近公共祖先

利用二叉搜索树的性质:对于某一个节点若是p与q都小于等于这个这个节点值,说明p、q都在这个节点的左子树,而最近的公共祖先也一定在这个节点的左子树;若是p与q都大于等于这个节点,说明p、q都在这个节点的右子树,而最近的公共祖先也一定在这个节点的右子树。

具体做法:

  • step 1:首先检查空节点,空树没有公共祖先。
  • step 2:对于某个节点,比较与p、q的大小,若p、q在该节点两边说明这就是最近公共祖先。
  • step 3:如果p、q都在该节点的左边,则递归进入左子树。
  • step 4:如果p、q都在该节点的右边,则递归进入右子树。
public int lowestCommonAncestor (TreeNode root, int p, int q) {if (root.val<p && root.val<q) {return lowestCommonAncestor(root.right,p,q);}if (root.val>p && root.val>q) {return lowestCommonAncestor(root.left,p,q);}return root.val;
}

42、在二叉树中找到两个节点的最近公共祖先

public int lowestCommonAncestor (TreeNode root, int o1, int o2) {// write code hereif(root == null) return -1;if(root.val == o1 || root.val == o2) return root.val; //和头有关//和头无关int left = lowestCommonAncestor(root.left, o1, o2); //左子树寻找公共祖先 , 子树信息int right = lowestCommonAncestor(root.right, o1, o2); //右子树寻找公共祖先 , 子树信息if(left != -1 && right != -1) return root.val; //左右子树找到了 整合出信息return left == -1 ? right : left;
}

43、序列化二叉树

import java.util.*;
public class Solution {StringBuilder sb = new StringBuilder();String Serialize(TreeNode root) {SerializeHelp(root, sb);return sb.toString();}TreeNode Deserialize(String str) {String[] values = str.split("_");//队列中存放分隔后的数据,value和#Queue<String> queue = new LinkedList<>();for (int i = 0; i < values.length; i++) {queue.offer(values[i]);}return DeserializeHelp(queue);}void SerializeHelp(TreeNode node, StringBuilder sb) {//先序遍历 null 为#_ ,其他分隔符为_if (node == null) {sb.append("#_");return; //结束}sb.append(node.val + "_");SerializeHelp(node.left, sb);SerializeHelp(node.right, sb);}TreeNode DeserializeHelp(Queue<String> queue) {String value = queue.poll();if (value.equals("#")) return null; //遇到# 表示空节点TreeNode node = new TreeNode(Integer.valueOf(value));node.left = DeserializeHelp(queue);node.right = DeserializeHelp(queue);return node;}
}

44、重建二叉树

public class Solution {HashMap<Integer, Integer> map = new HashMap<>();public TreeNode reConstructBinaryTree(int [] pre,int [] vin) {for(int i = 0; i < pre.length; i++){map.put(vin[i], i);//存放中序遍历}return build(pre, vin, 0, pre.length - 1, 0, pre.length - 1);}private TreeNode build(int [] pre,int [] vin, int pl, int pr, int vl, int vr){if(pl > pr || vl > vr) return null;int r = map.get(pre[pl]) - vl;//获取中序遍历的根节点TreeNode root = new TreeNode(pre[pl]);//左子树root.left = build(pre, vin, pl + 1, pl + r, vl, vl + r - 1);//右子树root.right = build(pre, vin, pl + r + 1, pr, vl + r + 1, vr);return root;}
}

45、输出二叉树的右视图

import java.util.*;public class Solution {public int[] solve (int[] xianxu, int[] zhongxu) {// write code here//1、重建树TreeNode root = rebuildTree(xianxu, zhongxu);//2、右视图List<Integer> list = new ArrayList<>();rightview(root,  list);//3、将list变为int[]int[] ans = new int[list.size()];for (int i = 0; i < list.size(); i++) {ans[i] = list.get(i);}return ans;}private TreeNode rebuildTree(int[] xianxu, int[] zhongxu) {int pl = xianxu.length;int ml = zhongxu.length;//分治算法if (pl == 0 || ml == 0) return null;TreeNode node = new TreeNode(xianxu[0]);//根//找到中序根中对应的第一个序号for (int i = 0; i < ml ; i++) {if (xianxu[0] == zhongxu[i]) {node.left = rebuildTree(Arrays.copyOfRange(xianxu, 1, i + 1),Arrays.copyOfRange(zhongxu, 0, i));node.right = rebuildTree(Arrays.copyOfRange(xianxu, i + 1, pl),Arrays.copyOfRange(zhongxu, i + 1, ml));break;}}return node;}private void rightview(TreeNode root, List<Integer> list) {//层序遍历if (root == null) return;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while (!queue.isEmpty()) {int size = queue.size();while (size-- != 0) {TreeNode node = queue.poll();if (node.left != null) queue.offer(node.left);if (node.right != null) queue.offer(node.right);if (size == 0) list.add(node.val); //层序的最后一个值}}}}

相关文章:

面试必刷101 Java题解 -- part 1

练习地址 面试必刷101-牛客1、链表反转2、链表内指定区间反转**3. 链表中的节点每k个一组翻转**4、**合并两个排序的链表**5、**合并k个已排序的链表**6、**判断链表中是否有环****7、链表中环的入口结点**8、链表中倒数最后k个结点**9、删除链表的倒数第n个节点****10、两个链…...

Python---关联与继承

专栏&#xff1a;python 个人主页&#xff1a;HaiFan. 专栏简介&#xff1a;Python在学&#xff0c;希望能够得到各位的支持&#xff01;&#xff01;&#xff01; 关联与继承前言has a关联关系is a继承关系子类不添加__init__子类添加__init__前言 has a关联关系 has - a 是在…...

数据库行业的 “叛逆者”:大数据已“死”,MotherDuck 当立

“大数据”已死——现今我们最重要的事情不是担心数据大小&#xff0c;而是专注于我们将如何使用它来做出更好的决策。数据库行业发展至今&#xff0c;在数据层面有很多的加速和变革&#xff0c;尤其是过去几年的云数仓爆炸式增长&#xff0c;带来了行业的很多变化。毫无疑问&a…...

Linux->进程优先级

目录 1. 优先级的概念 2. 优先级的运作方式 3. Linux下查看进程优先级以及调整 3.1 查看进程优先级 3.2 修改进程优先级 1. 优先级的概念 1. cpu资源分配的先后顺序&#xff0c;就是指进程的优先权&#xff08;priority&#xff09;。 2. 优先权高的进程有优先执行权利。配…...

loki 日志管理的安装部署使用

loki介绍 Loki是 Grafana Labs 团队最新的开源项目&#xff0c;是一个水平可扩展&#xff0c;高可用性&#xff0c;多租户的日志聚合系统。它的设计非常经济高效且易于操作&#xff0c;因为它不会为日志内容编制索引&#xff0c;而是为每个日志流编制一组标签。 不对日志进行…...

CTFer成长之路之反序列化漏洞

反序列化漏洞CTF 1.访问url&#xff1a; http://91a5ef16-ff14-4e0d-a687-32bdb4f61ecf.node3.buuoj.cn/ 点击下载源码 本地搭建环境并访问url&#xff1a; http://127.0.0.1/www/public/ 构造payload&#xff1a; ?sindex/index/hello&ethanwhoamiPOST的参数&#…...

Python学习-----模块5.0(文件管理大师-->os模块)

目录 前言&#xff1a; 1.os.getcwd() 2. os.listdir(path) 3.os.walk(path) 4.os.path.exists(path) 5.os.mkdir(path) 6.os.makedirs(path,exist_okTrue) 7.os.rmdir(path) 8.os.remove(path) 9.os.path.join(p1,p2) 10.os.path.split(path) 11.os.path.isdi…...

第45届世界技能大赛“网络安全”赛项浙江省选拔赛竞赛任务书

第45届世界技能大赛浙江省选拔赛竞赛任务书 一、竞赛时间 8:00-17:00&#xff0c;共计9小时。 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 模块A 任务1 数据库安全加固 8:00-10:00 50 任务2 文件MD5校验 50 任务3 Linux系统服务渗透测试及安全加…...

【uniapp微信小程序】跨平台使用echarts的方案选择踩坑

一、前言 使用Uniapp&#xff08;vue&#xff09;开发微信小程序&#xff0c;想用echarts图表实现类似github热力图的效果。 简要列一些可行或不可行的方案。 二、方案对比 1. 【应用】&#xff1a;微信小程序原生开发 有echarts官网提供的跨平台方案&#xff1a;在微信小程…...

WAF渗透攻防实践(16)

预备知识 WAF&#xff1a;WEB攻击一直是黑客攻击的主流手段&#xff0c;WAF作为网站安全基础设施的标配。Web Application Firewall&#xff0c;Web应用防火墙&#xff0c;通过执行一系列针对HTTP/HTTPS的安全策略来专门为Web应用提供保护的产品。 Nginx&#xff1a;Nginx 是…...

高并发场景下机器性能优化sop

之前接触过一些高并发场景下的性能优化&#xff0c;最近过年时候又碰巧看了一些相关资料&#xff0c;趁着还没忘干净&#xff0c;手动整理一下&#xff0c;有一些是在别处看到的&#xff0c;有一些是自己的亲身经历&#xff0c;因为偏向于自己整理笔记所以很多地方都只是列了一…...

【女程序员进大厂面试经验】

*那些犹豫想做技术又不敢的女生一定不要胆怯&#xff0c;就认准了这条路坚持走下去。大三的学生已经可以开始投简历、寻找面试机会了。先说一下我的情况吧&#xff01;我是郑州一双普通本科的女大学生&#xff0c;刚找工作的时候也很迷茫。同班的女生有做产品的、有做前端的、还…...

计算机网络笔记(复试准备)第一章

计算机网络笔记&#xff08;复试准备&#xff09; 第一章 网络&#xff0c;互联网与因特网 网络由若干个结点和连接这些结点的链路组成 多个网络通过路由器连接起来这也就形成了一个更大的网络即是我们熟知的互联网也就是“网络的网络” 因特网是世界上最大的网络 问&#xf…...

WooCommerce 上传文件 Vanquish v71.6

今天用wp 搭一个b2c外贸跨境电商网站 找 了一个文件上传插件&#xff0c;可以 上传无限数量的文件&#xff0c;没有文件大小限制WooCommerce 上传文件允许您上传无限数量的文件&#xff0c;没有任何文件大小限制。得益于其创新的块上传技术&#xff0c;它可以不受限制地上传任何…...

zabbix4.0 Web页面配置 - 聚合图形的实现

目录 1、主机组Host groups配置 创建主机组 ​编辑 将一个主机添加至刚才创建的主机里面 2、用户参数UserParameter设置 示例&#xff1a; 添加一个参数&#xff1a;show.host.messages 模拟zabbix模板里面的参数再添加一个userparameter 3、触发器设置 示例&#xff1a; …...

计算机网络 — UDP协议(看这一篇就可以

UDP协议UDP是传输层的重要协议之一&#xff0c;另一重要协议为TCP协议。两者对比&#xff1a;TCP协议复杂&#xff0c;但传输可靠。UDP协议简单&#xff0c;但传输不可靠。UDP协议全称为&#xff1a;User Datagram Protocol&#xff08;用户数据报协议&#xff09;。它是一个简…...

Pikachu靶场(暴力破解)

目录标题暴力破解&#xff08;登录&#xff09;基于表单的暴力破解验证码绕过(on server)验证码绕过(on client)token防爆破?上学期用这个靶场写过作业&#xff0c;现在抽空给它过一遍&#xff0c;由于需要抓包&#xff0c;从而通过小皮&#xff0c;使用本地&#xff08;127.0…...

浅谈script,link,import,@import引入

一.页面导入样式&#xff0c;使用link和import有什么区别 链接式和导入式有什么区别&#xff08;链接式&#xff0c;导入式&#xff0c;内嵌式&#xff0c;行内&#xff09; 1.从属关系:link是html标签&#xff0c;import是css提供的. 2.加载差异:页面加载时&#xff0c;link会…...

【CSS】CSS 层叠样式表 ① ( 简介 | CSS 引入方式 - 内联样式 | 内联样式语法 | 内联样式缺点 )

文章目录一、CSS 层叠样式表二、CSS 引入方式 - 内联样式1、内联样式语法2、内联样式缺点3、内联样式代码示例① 核心代码示例② 完整代码示例③ 执行结果一、CSS 层叠样式表 CSS 全称 Cascading Style Sheets , 层叠样式表 ; 作用如下 : 设置 HTML 页面 文本内容 的 字体 , 颜…...

12.STM32系统定时器-SysTick

目录 1.系统定时器-SysTick 2.SysTick定时时间的计算 3.SysTick结构体 4.SysTick固件库函数 5.SysTick中断优先级 1.系统定时器-SysTick SysTick:24位系统定时器&#xff0c;只能递减&#xff0c;存在于内核嵌套在NVIC中。所有的Cortex-M中都有这个系统定时器。 重装载值…...

28张图讲解支付系统的通用设计,漂亮!

支付永远是一个公司的核心领域&#xff0c;因为这是一个有交易属性公司的命脉。那么&#xff0c;支付系统到底长什么样&#xff0c;又是怎么运行交互的呢&#xff1f;抛开带有支付牌照的金融公司的支付架构&#xff0c;下述链路和系统组成基本上符合绝大多数支付场景。其实整体…...

【5】linux命令每日分享——touch创建文件

大家好&#xff0c;这里是sdust-vrlab&#xff0c;Linux是一种免费使用和自由传播的类UNIX操作系统&#xff0c;Linux的基本思想有两点&#xff1a;一切都是文件&#xff1b;每个文件都有确定的用途&#xff1b;linux涉及到IT行业的方方面面&#xff0c;在我们日常的学习中&…...

TypeScript快速上手语法+结合vue3用法

TypeScript快速上手语法结合vue3用法 前言&#xff1a; 本篇内容不涉及TypeScript安装以及配置&#xff0c;具体安装及配置篇可以看下面目录&#xff0c;本篇只涉及TypeScript语法相关内容&#xff0c;及结合vue3的用法。不讲废话&#xff0c;简单直接直接开撸。 目录 Type…...

一,下载iPerf3最新源代码

本文目录普通下载方式&#xff1a;git下载方式&#xff1a;普通下载方式&#xff1a; 如果你只是要阅读源代码&#xff0c;不涉及到编译安装修改源代码&#xff0c;那么可以简单的通过此方式下载代码。如果你希望编译安装修改源代码&#xff0c;那么建议通过git来进行源代码的…...

keithley6487/吉时利6487皮安表

产品概览 5-1/2 位 Keithley 6487 皮安表/电压源改进了屡获殊荣的 Keithley 6485 皮安表的测量能力&#xff0c;并增加了高分辨率 500V 电源。它提供更高的精度和更快的上升时间&#xff0c;以及与电容设备一起使用的阻尼功能。这款经济高效的仪器具有八个电流测量范围和高速自…...

sql命令大全

一&#xff1a;基本命令 1.数据库连接 mysql -h 主机名 -u root -p2.添加用户 insert into user (host,user,password,select_priv,insert_priv,update_priv) values (localhost,guest,password(guest123),Y,Y,Y);3.创建用户 create user usernamehost identified by passw…...

Ubuntu 定时执行脚本

一、关于crontab cron是一个Linux定时执行工具&#xff0c;可以在无需人工干预的情况下运行作业。在Ubuntu中&#xff0c;cron是被默认安装并启动的。 二、例子 直接上例子&#xff0c;来看看怎么用。 需求&#xff1a;定时每天8点&#xff0c;自动执行保存在/root目录下he…...

Python带你制作一个属于自己的多功能音乐播放器

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 就是用Python做一个简易的音乐播放器&#xff0c;废话不多说&#xff0c;咱们直接开干 当然&#xff0c;今天做这个肯定不是最简单的&#xff0c;最简单的音乐播放器&#xff0c;9行代码足以 完整源码等直接在文末名片领…...

Redis 被问麻了...

Redis是面试中绕不过的槛&#xff0c;只要在简历中写了用过Redis&#xff0c;肯定逃不过。今天我们就来模拟一下面试官在Redis这个话题上是如何一步一步深入&#xff0c;全面考察候选人对于Redis的掌握情况。 小张&#xff1a; 面试官&#xff0c;你好。我是来参加面试的。 …...

使用JavaScript+Selenium玩转Web应用自动化测试

自动化测试 在软件开发过程中, 测试是功能验收的必要过程, 这个过程往往有测试人员参与, 提前编写测试用例, 然后再手动对测试用例进行测试, 测试用例都通过之后则可以认为该功能通过验收. 但是软件中多个功能之间往往存在关联或依赖关系, 某一个功能的新增或修改可能或影响到…...