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

有序表常见题型

给定一个数组arr和两个整数a和b求arr中有多少个子数组累加和在a到b这个范围上返回达标的子数组数量

如【3,6,1,9,2】达标的子数组通过暴力求解的方式时间复杂度为O(N的三次方)【找每个子数组占用O(N的二次方)的时间复杂度,然后再算每个子数组的和占用O(N)的时间复杂度总的占用了O(N的三次方的时间复杂度)】
用前缀和的思想可以将时间复杂度降低到O(N的二次方的时间复杂度)

这个题有一个O(N*logN的解法)
分析:假设现在来到i位置,子数组必须以i位置的数结尾达标的有多少个,依次计算,最后求和则得到最终的结果。
假设要求必须以17结尾的子数组范围在[10,60]的有多少个,
假设现在0-17的前缀和是100,假设0-5的前缀和是5,那么可以推出6-17的累加和为95。
那么只要能够找到任何一个前缀和落在[40,90]的范围,那么就能得到以17结尾的子数组落在[10,60]范围。
做法:
有如下数组:
[3,-2,4,3,6,-1] 范围是[1,5]的,假设有一个结构,这个结构是接收前缀和的,那么对于遍历到的当前数x,则需要判断当前数x是否在[1,5]的范围上,以及它的前缀和是否存在落在[sum(x)-5,sum(x)-1]范围上。
那么对于如上数组:
第一步:首先是一个数也没有的时候,我的前缀和结构提前放入一个0,我要整体以0位置结尾落在1-5的范围上,我就在结构中查有多少个前缀和落在[-2,2]上,发现有一个,然后我再将自己的前缀和3扔进前缀和结构
在这里插入图片描述
第二步:来到1位置,整体前缀和是1,那么则需要找到在这个前缀和结构中范围落在[-4,0]上面,发现有1个,然后我再将1位置的前缀和加入
在这里插入图片描述
第三步:来到2位置,前缀和为5,那么需要找到有多少前缀和范围落在[0,4]范围上,发现有三个,再将5加入结构中。
依次类推下去得到最终的结果。

如何实现这个前缀和结构:
结构的特点:
1、这个结构能往里加整数
2、能够接收一个数字范围并且能够返回满足数字范围上的数有多少个
3、这个结构能接收重复的数字(我多个范围可能有相同的前缀和)
那么我可以做一个小于某个key值的接口把范围内的数给拼接出来。
问题:
有序表是不能有重复数字,解决方案:
我们可以将重复数字压在一起从而实现解决。

public class CountofRangeSum {public static int countRangeSum1(int[] nums, int lower, int upper) {int n = nums.length;long[] sums = new long[n + 1];for (int i = 0; i < n; ++i)sums[i + 1] = sums[i] + nums[i];return countWhileMergeSort(sums, 0, n + 1, lower, upper);}private static int countWhileMergeSort(long[] sums, int start, int end, int lower, int upper) {if (end - start <= 1)return 0;int mid = (start + end) / 2;int count = countWhileMergeSort(sums, start, mid, lower, upper)+ countWhileMergeSort(sums, mid, end, lower, upper);int j = mid, k = mid, t = mid;long[] cache = new long[end - start];for (int i = start, r = 0; i < mid; ++i, ++r) {while (k < end && sums[k] - sums[i] < lower)k++;while (j < end && sums[j] - sums[i] <= upper)j++;while (t < end && sums[t] < sums[i])cache[r++] = sums[t++];cache[r] = sums[i];count += j - k;}System.arraycopy(cache, 0, sums, start, t - start);return count;}public static class SBTNode {//参与排序的keypublic long key;//左孩子右孩子public SBTNode l;public SBTNode r;//平衡因子public long size; // 不同key的size//附加的数据项public long all; // 总的sizepublic SBTNode(long k) {key = k;size = 1;all = 1;}}public static class SizeBalancedTreeSet {private SBTNode root;private HashSet<Long> set = new HashSet<>();private SBTNode rightRotate(SBTNode cur) {long same = cur.all - (cur.l != null ? cur.l.all : 0) - (cur.r != null ? cur.r.all : 0);SBTNode leftNode = cur.l;cur.l = leftNode.r;leftNode.r = cur;leftNode.size = cur.size;cur.size = (cur.l != null ? cur.l.size : 0) + (cur.r != null ? cur.r.size : 0) + 1;// all modifyleftNode.all = cur.all;cur.all = (cur.l != null ? cur.l.all : 0) + (cur.r != null ? cur.r.all : 0) + same;return leftNode;}private SBTNode leftRotate(SBTNode cur) {long same = cur.all - (cur.l != null ? cur.l.all : 0) - (cur.r != null ? cur.r.all : 0);SBTNode rightNode = cur.r;cur.r = rightNode.l;rightNode.l = cur;rightNode.size = cur.size;cur.size = (cur.l != null ? cur.l.size : 0) + (cur.r != null ? cur.r.size : 0) + 1;// all modifyrightNode.all = cur.all;cur.all = (cur.l != null ? cur.l.all : 0) + (cur.r != null ? cur.r.all : 0) + same;return rightNode;}private SBTNode maintain(SBTNode cur) {if (cur == null) {return null;}long leftSize = cur.l != null ? cur.l.size : 0;long leftLeftSize = cur.l != null && cur.l.l != null ? cur.l.l.size : 0;long leftRightSize = cur.l != null && cur.l.r != null ? cur.l.r.size : 0;long rightSize = cur.r != null ? cur.r.size : 0;long rightLeftSize = cur.r != null && cur.r.l != null ? cur.r.l.size : 0;long rightRightSize = cur.r != null && cur.r.r != null ? cur.r.r.size : 0;if (leftLeftSize > rightSize) {cur = rightRotate(cur);cur.r = maintain(cur.r);cur = maintain(cur);} else if (leftRightSize > rightSize) {cur.l = leftRotate(cur.l);cur = rightRotate(cur);cur.l = maintain(cur.l);cur.r = maintain(cur.r);cur = maintain(cur);} else if (rightRightSize > leftSize) {cur = leftRotate(cur);cur.l = maintain(cur.l);cur = maintain(cur);} else if (rightLeftSize > leftSize) {cur.r = rightRotate(cur.r);cur = leftRotate(cur);cur.l = maintain(cur.l);cur.r = maintain(cur.r);cur = maintain(cur);}return cur;}private SBTNode add(SBTNode cur, long key, boolean contains) {if (cur == null) {return new SBTNode(key);} else {cur.all++;if (key == cur.key) {return cur;} else { // 还在左滑或者右滑if (!contains) {cur.size++;}if (key < cur.key) {cur.l = add(cur.l, key, contains);} else {cur.r = add(cur.r, key, contains);}return maintain(cur);}}}public void add(long sum) {boolean contains = set.contains(sum);root = add(root, sum, contains);set.add(sum);}public long lessKeySize(long key) {SBTNode cur = root;long ans = 0;while (cur != null) {if (key == cur.key) {//左树不为空则加上左树的allreturn ans + (cur.l != null ? cur.l.all : 0);} else if (key < cur.key) {cur = cur.l;} else {ans += cur.all - (cur.r != null ? cur.r.all : 0);cur = cur.r;}}return ans;}// > 7 8...// <8 ...<=7public long moreKeySize(long key) {return root != null ? (root.all - lessKeySize(key + 1)) : 0;}}public static int countRangeSum2(int[] nums, int lower, int upper) {// 黑盒,加入数字(前缀和),不去重,可以接受重复数字//支持查询 < num , 有几个数?SizeBalancedTreeSet treeSet = new SizeBalancedTreeSet();long sum = 0;int ans = 0;treeSet.add(0);// 一个数都没有的时候,就已经有一个前缀和累加和为0,for (int i = 0; i < nums.length; i++) {sum += nums[i];//之前有多少个前缀和落在[sum - upper, sum - lower]// [10, 20] ? 如果要查落在10到20范围上的数有多少个// 那么需要查< 10 的有多少个  < 21 的有多少个long a = treeSet.lessKeySize(sum - lower + 1);long b = treeSet.lessKeySize(sum - upper);//加上结果ans += a - b;//放入当前前缀和treeSet.add(sum);}return ans;}// for testpublic static void printArray(int[] arr) {for (int i = 0; i < arr.length; i++) {System.out.print(arr[i] + " ");}System.out.println();}// for testpublic static int[] generateArray(int len, int varible) {int[] arr = new int[len];for (int i = 0; i < arr.length; i++) {arr[i] = (int) (Math.random() * varible);}return arr;}public static void main(String[] args) {int len = 200;int varible = 50;for (int i = 0; i < 10000; i++) {int[] test = generateArray(len, varible);int lower = (int) (Math.random() * varible) - (int) (Math.random() * varible);int upper = lower + (int) (Math.random() * varible);int ans1 = countRangeSum1(test, lower, upper);int ans2 = countRangeSum2(test, lower, upper);if (ans1 != ans2) {printArray(test);System.out.println(lower);System.out.println(upper);System.out.println(ans1);System.out.println(ans2);}}}}

有一个滑动窗口:

1)L是滑动窗口最左位置,R是滑动窗口最右位置,一开始LR都在数组左侧
2)任何一步都可能R往右移动表示某个数进了窗口
3)任何一步都可能L往右动,表示某个数出了窗口
想知道每一个窗口状态的中位数

还是想象有这样一个结构:
1)这个结构可以接收数字,也可以支持一个一个删除数也可以都删除
2)如果n等于奇数则取中间的数,如果为偶数则取中间两个数除以2
3)可以加入重复数字

public class SlidingWindowMedian {public static class SBTNode<K extends Comparable<K>> {public K key;public SBTNode<K> l;public SBTNode<K> r;public int size;public SBTNode(K k) {key = k;size = 1;}}public static class SizeBalancedTreeMap<K extends Comparable<K>> {private SBTNode<K> root;private SBTNode<K> rightRotate(SBTNode<K> cur) {SBTNode<K> leftNode = cur.l;cur.l = leftNode.r;leftNode.r = cur;leftNode.size = cur.size;cur.size = (cur.l != null ? cur.l.size : 0) + (cur.r != null ? cur.r.size : 0) + 1;return leftNode;}private SBTNode<K> leftRotate(SBTNode<K> cur) {SBTNode<K> rightNode = cur.r;cur.r = rightNode.l;rightNode.l = cur;rightNode.size = cur.size;cur.size = (cur.l != null ? cur.l.size : 0) + (cur.r != null ? cur.r.size : 0) + 1;return rightNode;}private SBTNode<K> maintain(SBTNode<K> cur) {if (cur == null) {return null;}int leftSize = cur.l != null ? cur.l.size : 0;int leftLeftSize = cur.l != null && cur.l.l != null ? cur.l.l.size : 0;int leftRightSize = cur.l != null && cur.l.r != null ? cur.l.r.size : 0;int rightSize = cur.r != null ? cur.r.size : 0;int rightLeftSize = cur.r != null && cur.r.l != null ? cur.r.l.size : 0;int rightRightSize = cur.r != null && cur.r.r != null ? cur.r.r.size : 0;if (leftLeftSize > rightSize) {cur = rightRotate(cur);cur.r = maintain(cur.r);cur = maintain(cur);} else if (leftRightSize > rightSize) {cur.l = leftRotate(cur.l);cur = rightRotate(cur);cur.l = maintain(cur.l);cur.r = maintain(cur.r);cur = maintain(cur);} else if (rightRightSize > leftSize) {cur = leftRotate(cur);cur.l = maintain(cur.l);cur = maintain(cur);} else if (rightLeftSize > leftSize) {cur.r = rightRotate(cur.r);cur = leftRotate(cur);cur.l = maintain(cur.l);cur.r = maintain(cur.r);cur = maintain(cur);}return cur;}private SBTNode<K> findLastIndex(K key) {SBTNode<K> pre = root;SBTNode<K> cur = root;while (cur != null) {pre = cur;if (key.compareTo(cur.key) == 0) {break;} else if (key.compareTo(cur.key) < 0) {cur = cur.l;} else {cur = cur.r;}}return pre;}private SBTNode<K> add(SBTNode<K> cur, K key) {if (cur == null) {return new SBTNode<K>(key);} else {cur.size++;if (key.compareTo(cur.key) < 0) {cur.l = add(cur.l, key);} else {cur.r = add(cur.r, key);}return maintain(cur);}}private SBTNode<K> delete(SBTNode<K> cur, K key) {cur.size--;if (key.compareTo(cur.key) > 0) {cur.r = delete(cur.r, key);} else if (key.compareTo(cur.key) < 0) {cur.l = delete(cur.l, key);} else {if (cur.l == null && cur.r == null) {// free cur memory -> C++cur = null;} else if (cur.l == null && cur.r != null) {// free cur memory -> C++cur = cur.r;} else if (cur.l != null && cur.r == null) {// free cur memory -> C++cur = cur.l;} else {SBTNode<K> pre = null;SBTNode<K> des = cur.r;des.size--;while (des.l != null) {pre = des;des = des.l;des.size--;}if (pre != null) {pre.l = des.r;des.r = cur.r;}des.l = cur.l;des.size = des.l.size + (des.r == null ? 0 : des.r.size) + 1;// free cur memory -> C++cur = des;}}return cur;}private SBTNode<K> getIndex(SBTNode<K> cur, int kth) {if (kth == (cur.l != null ? cur.l.size : 0) + 1) {return cur;} else if (kth <= (cur.l != null ? cur.l.size : 0)) {return getIndex(cur.l, kth);} else {return getIndex(cur.r, kth - (cur.l != null ? cur.l.size : 0) - 1);}}public int size() {return root == null ? 0 : root.size;}public boolean containsKey(K key) {if (key == null) {throw new RuntimeException("invalid parameter.");}SBTNode<K> lastNode = findLastIndex(key);return lastNode != null && key.compareTo(lastNode.key) == 0 ? true : false;}public void add(K key) {if (key == null) {throw new RuntimeException("invalid parameter.");}SBTNode<K> lastNode = findLastIndex(key);if (lastNode == null || key.compareTo(lastNode.key) != 0) {root = add(root, key);}}public void remove(K key) {if (key == null) {throw new RuntimeException("invalid parameter.");}if (containsKey(key)) {root = delete(root, key);}}public K getIndexKey(int index) {if (index < 0 || index >= this.size()) {throw new RuntimeException("invalid parameter.");}return getIndex(root, index + 1).key;}}public static class Node implements Comparable<Node> {public int index;public int value;public Node(int i, int v) {index = i;value = v;}@Overridepublic int compareTo(Node o) {return value != o.value ? Integer.valueOf(value).compareTo(o.value): Integer.valueOf(index).compareTo(o.index);}}public static double[] medianSlidingWindow(int[] nums, int k) {SizeBalancedTreeMap<Node> map = new SizeBalancedTreeMap<>();for (int i = 0; i < k - 1; i++) {map.add(new Node(i, nums[i]));}double[] ans = new double[nums.length - k + 1];int index = 0;for (int i = k - 1; i < nums.length; i++) {map.add(new Node(i, nums[i]));if (map.size() % 2 == 0) {Node upmid = map.getIndexKey(map.size() / 2 - 1);Node downmid = map.getIndexKey(map.size() / 2);ans[index++] = ((double) upmid.value + (double) downmid.value) / 2;} else {Node mid = map.getIndexKey(map.size() / 2);ans[index++] = (double) mid.value;}map.remove(new Node(i - k + 1, nums[i - k + 1]));}return ans;}}

高效实现ArrayList的add(index,num),get(index),remove(index)方法要求时间复杂度为LogN

假设维持一棵树A左边出现的点的自然时序都比它早,然后A的右树自然时序都比A晚,S的自然时序都比B早,k的自然时序都比B晚
在这里插入图片描述

假设现在我们要左旋:
在这里插入图片描述
我的自然时序依然不变。

public class AddRemoveGetIndexGreat {public static class SBTNode<V> {public V value;public SBTNode<V> l;public SBTNode<V> r;public int size;public SBTNode(V v) {value = v;size = 1;}}public static class SbtList<V> {private SBTNode<V> root;private SBTNode<V> rightRotate(SBTNode<V> cur) {SBTNode<V> leftNode = cur.l;cur.l = leftNode.r;leftNode.r = cur;leftNode.size = cur.size;cur.size = (cur.l != null ? cur.l.size : 0) + (cur.r != null ? cur.r.size : 0) + 1;return leftNode;}private SBTNode<V> leftRotate(SBTNode<V> cur) {SBTNode<V> rightNode = cur.r;cur.r = rightNode.l;rightNode.l = cur;rightNode.size = cur.size;cur.size = (cur.l != null ? cur.l.size : 0) + (cur.r != null ? cur.r.size : 0) + 1;return rightNode;}private SBTNode<V> maintain(SBTNode<V> cur) {if (cur == null) {return null;}int leftSize = cur.l != null ? cur.l.size : 0;int leftLeftSize = cur.l != null && cur.l.l != null ? cur.l.l.size : 0;int leftRightSize = cur.l != null && cur.l.r != null ? cur.l.r.size : 0;int rightSize = cur.r != null ? cur.r.size : 0;int rightLeftSize = cur.r != null && cur.r.l != null ? cur.r.l.size : 0;int rightRightSize = cur.r != null && cur.r.r != null ? cur.r.r.size : 0;if (leftLeftSize > rightSize) {cur = rightRotate(cur);cur.r = maintain(cur.r);cur = maintain(cur);} else if (leftRightSize > rightSize) {cur.l = leftRotate(cur.l);cur = rightRotate(cur);cur.l = maintain(cur.l);cur.r = maintain(cur.r);cur = maintain(cur);} else if (rightRightSize > leftSize) {cur = leftRotate(cur);cur.l = maintain(cur.l);cur = maintain(cur);} else if (rightLeftSize > leftSize) {cur.r = rightRotate(cur.r);cur = leftRotate(cur);cur.l = maintain(cur.l);cur.r = maintain(cur.r);cur = maintain(cur);}return cur;}private SBTNode<V> add(SBTNode<V> root, int index, SBTNode<V> cur) {if (root == null) {return cur;}root.size++;int leftAndHeadSize = (root.l != null ? root.l.size : 0) + 1;if (index < leftAndHeadSize) {root.l = add(root.l, index, cur);} else {root.r = add(root.r, index - leftAndHeadSize, cur);}root = maintain(root);return root;}private SBTNode<V> remove(SBTNode<V> root, int index) {root.size--;int rootIndex = root.l != null ? root.l.size : 0;if (index != rootIndex) {if (index < rootIndex) {root.l = remove(root.l, index);} else {root.r = remove(root.r, index - rootIndex - 1);}return root;}if (root.l == null && root.r == null) {return null;}if (root.l == null) {return root.r;}if (root.r == null) {return root.l;}SBTNode<V> pre = null;SBTNode<V> suc = root.r;suc.size--;while (suc.l != null) {pre = suc;suc = suc.l;suc.size--;}if (pre != null) {pre.l = suc.r;suc.r = root.r;}suc.l = root.l;suc.size = suc.l.size + (suc.r == null ? 0 : suc.r.size) + 1;return suc;}private SBTNode<V> get(SBTNode<V> root, int index) {int leftSize = root.l != null ? root.l.size : 0;if (index < leftSize) {return get(root.l, index);} else if (index == leftSize) {return root;} else {return get(root.r, index - leftSize - 1);}}public void add(int index, V num) {SBTNode<V> cur = new SBTNode<V>(num);if (root == null) {root = cur;} else {if (index <= root.size) {root = add(root, index, cur);}}}public V get(int index) {SBTNode<V> ans = get(root, index);return ans.value;}public void remove(int index) {if (index >= 0 && size() > index) {root = remove(root, index);}}public int size() {return root == null ? 0 : root.size;}}// 通过以下这个测试,// 可以很明显的看到LinkedList的插入、删除、get效率不如SbtList// LinkedList需要找到index所在的位置之后才能插入或者读取,时间复杂度O(N)// SbtList是平衡搜索二叉树,所以插入或者读取时间复杂度都是O(logN)public static void main(String[] args) {// 功能测试int test = 50000;int max = 1000000;boolean pass = true;ArrayList<Integer> list = new ArrayList<>();SbtList<Integer> sbtList = new SbtList<>();for (int i = 0; i < test; i++) {if (list.size() != sbtList.size()) {pass = false;break;}if (list.size() > 1 && Math.random() < 0.5) {int removeIndex = (int) (Math.random() * list.size());list.remove(removeIndex);sbtList.remove(removeIndex);} else {int randomIndex = (int) (Math.random() * (list.size() + 1));int randomValue = (int) (Math.random() * (max + 1));list.add(randomIndex, randomValue);sbtList.add(randomIndex, randomValue);}}for (int i = 0; i < list.size(); i++) {if (!list.get(i).equals(sbtList.get(i))) {pass = false;break;}}System.out.println("功能测试是否通过 : " + pass);// 性能测试test = 500000;list = new ArrayList<>();sbtList = new SbtList<>();long start = 0;long end = 0;start = System.currentTimeMillis();for (int i = 0; i < test; i++) {int randomIndex = (int) (Math.random() * (list.size() + 1));int randomValue = (int) (Math.random() * (max + 1));list.add(randomIndex, randomValue);}end = System.currentTimeMillis();System.out.println("ArrayList插入总时长(毫秒) : " + (end - start));start = System.currentTimeMillis();for (int i = 0; i < test; i++) {int randomIndex = (int) (Math.random() * (i + 1));list.get(randomIndex);}end = System.currentTimeMillis();System.out.println("ArrayList读取总时长(毫秒) : " + (end - start));start = System.currentTimeMillis();for (int i = 0; i < test; i++) {int randomIndex = (int) (Math.random() * list.size());list.remove(randomIndex);}end = System.currentTimeMillis();System.out.println("ArrayList删除总时长(毫秒) : " + (end - start));start = System.currentTimeMillis();for (int i = 0; i < test; i++) {int randomIndex = (int) (Math.random() * (sbtList.size() + 1));int randomValue = (int) (Math.random() * (max + 1));sbtList.add(randomIndex, randomValue);}end = System.currentTimeMillis();System.out.println("SbtList插入总时长(毫秒) : " + (end - start));start = System.currentTimeMillis();for (int i = 0; i < test; i++) {int randomIndex = (int) (Math.random() * (i + 1));sbtList.get(randomIndex);}end = System.currentTimeMillis();System.out.println("SbtList读取总时长(毫秒) :  " + (end - start));start = System.currentTimeMillis();for (int i = 0; i < test; i++) {int randomIndex = (int) (Math.random() * sbtList.size());sbtList.remove(randomIndex);}end = System.currentTimeMillis();System.out.println("SbtList删除总时长(毫秒) :  " + (end - start));}}

红黑树的基本概念

1)AVL树它的平衡性来自于左树及右树的高度差小于等于1
2)SB树任何一个叔叔节点的个数不小于侄子节点,保证节点较少的树和节点较大的树的数量不超过两倍以上

红黑树定义
1)每个节点不是红就是黑
2)整棵树的头节点一定是黑,叶节点也一定为黑
3)节点有黑有红的情况下两个红节点不能相邻
4)每一颗子树任何一条链黑节点的数量要一样
最长的链条一定是红黑相间的,最短的链一定是只有黑节点的,且长度不会超过两倍以上。此优点是防止像AVL树一样删除和增加节点的时候就马上调整平衡性。对于硬盘的IO消耗比较低
插入有5种情况,删除有8种情况。

相关文章:

  • DBS note7 (end):DB Design
  • Google Guava 反射工具使用详解
  • Docker容器网络模式
  • Blender学习笔记:小车狂奔动画
  • 安卓8预装可卸载应用
  • [数据结构]HashSet与LinkedHashSet的底层原理学习心得
  • Git 标签管理
  • Jupyter Markdown 插入图片
  • Kettle 安装配置
  • SpringSecurity和JWT实现认证和授权
  • 聊聊logback的ThrowableProxyConverter
  • prometheus基础,结合node_exporter监控节点
  • 【数组】-Lc15-三数之和(排序+for循环+滑动窗口)
  • 详细学习Pyqt5的10种容器(Containers)
  • 【自动化测试】pytest 用例执行中print日志实时输出
  • Angular6错误 Service: No provider for Renderer2
  • docker python 配置
  • dva中组件的懒加载
  • JAVA多线程机制解析-volatilesynchronized
  • MySQL QA
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • Webpack 4 学习01(基础配置)
  • 关于 Cirru Editor 存储格式
  • 判断客户端类型,Android,iOS,PC
  • 前端攻城师
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • 树莓派用上kodexplorer也能玩成私有网盘
  • #控制台大学课堂点名问题_课堂随机点名
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (翻译)Entity Framework技巧系列之七 - Tip 26 – 28
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (十三)Maven插件解析运行机制
  • (四)Controller接口控制器详解(三)
  • (一)80c52学习之旅-起始篇
  • .aanva
  • .NET Core 和 .NET Framework 中的 MEF2
  • .NET 动态调用WebService + WSE + UsernameToken
  • .NET 事件模型教程(二)
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .Net下的签名与混淆
  • @在php中起什么作用?
  • [ web基础篇 ] Burp Suite 爆破 Basic 认证密码
  • [ai笔记4] 将AI工具场景化,应用于生活和工作
  • [BPU部署教程] 教你搞定YOLOV5部署 (版本: 6.2)
  • [FZSZOJ 1223] 上海红茶馆
  • [IE编程] 如何在IE8 下调试BHO控件/工具栏(调试Tab进程)
  • [jquery]this触发自身click事件,当前控件向上滑出
  • [NCTF2019]True XML cookbook
  • [Oh My C++ Diary]\t \n \r的用法
  • [PyTorch][chapter 60][强化学习-2-有模型学习2]
  • [RK-Linux] RK3399支持M.2 NVMe SSD启动
  • [RK-Linux] 移植Linux-5.10到RK3399(六)| 检查GMAC(RTL8211F)配置使能千兆以太网
  • [Socket]Unix socket 运行权限问题
  • [Spring Boot 3] 整合NoSQL与构建RESTful服务