排序题目:计算右侧小于当前元素的个数

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 前言
  • 解法一
    • 思路和算法
    • 代码
    • 复杂度分析
  • 解法二
    • 预备知识
    • 思路和算法
    • 代码
    • 复杂度分析
  • 解法三
    • 预备知识
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:计算右侧小于当前元素的个数

出处:315. 计算右侧小于当前元素的个数

难度

8 级

题目描述

要求

给定一个整数数组 nums \texttt{nums} nums,返回一个新数组 counts \texttt{counts} counts。数组 counts \texttt{counts} counts 有该性质: counts[i] \texttt{counts[i]} counts[i] 的值是 nums[i] \texttt{nums[i]} nums[i] 右侧小于 nums[i] \texttt{nums[i]} nums[i] 的元素的数量。

示例

示例 1:

输入: nums = [5,2,6,1] \texttt{nums = [5,2,6,1]} nums = [5,2,6,1]
输出: [2,1,1,0] \texttt{[2,1,1,0]} [2,1,1,0]
解释:
5 \texttt{5} 5 的右侧有 2 \texttt{2} 2 个更小的元素( 2 \texttt{2} 2 1 \texttt{1} 1)。
2 \texttt{2} 2 的右侧有 1 \texttt{1} 1 个更小的元素( 1 \texttt{1} 1)。
6 \texttt{6} 6 的右侧有 1 \texttt{1} 1 个更小的元素( 1 \texttt{1} 1)。
1 \texttt{1} 1 的右侧有 0 \texttt{0} 0 个更小的元素。

示例 2:

输入: nums = [-1] \texttt{nums = [-1]} nums = [-1]
输出: [0] \texttt{[0]} [0]

示例 3:

输入: nums = [-1,-1] \texttt{nums = [-1,-1]} nums = [-1,-1]
输出: [0,0] \texttt{[0,0]} [0,0]

数据范围

  • 1 ≤ nums.length ≤ 10 5 \texttt{1} \le \texttt{nums.length} \le \texttt{10}^\texttt{5} 1nums.length105
  • -10 4 ≤ nums[i] ≤ 10 4 \texttt{-10}^\texttt{4} \le \texttt{nums[i]} \le \texttt{10}^\texttt{4} -104nums[i]104

前言

定义「逆序对」的概念如下:对于下标 i i i j j j,如果 i < j i < j i<j nums [ i ] > nums [ j ] \textit{nums}[i] > \textit{nums}[j] nums[i]>nums[j],则下标对 ( i , j ) (i, j) (i,j) 是一个逆序对。

这道题要求计算数组 nums \textit{nums} nums 中的每个元素右侧小于当前元素的个数,实质是计算每个元素右侧的元素中与当前元素形成逆序对的元素个数。

对于长度为 n n n 的数组,最朴素的计算逆序对的数量的方法是对于每个元素遍历其右边的元素并统计可以形成逆序对的元素个数,每个元素需要 O ( n ) O(n) O(n) 的时间计算逆序对的个数,总时间复杂度是 O ( n 2 ) O(n^2) O(n2)。由于数组 nums \textit{nums} nums 的长度最大为 1 0 5 10^5 105,因此 O ( n 2 ) O(n^2) O(n2) 的时间复杂度过高,必须使用时间复杂度更低的方法。

以下介绍三种时间复杂度 O ( n log ⁡ n ) O(n \log n) O(nlogn) 的计算逆序对数量的方法,分别是归并排序、线段树和树状数组。

解法一

思路和算法

由于逆序对和排序相关,因此可以使用排序的思想计算逆序对的数量。归并排序的过程中,每次将两个升序子数组合并,合并的过程中即可发现这两个升序子数组中的逆序对。因此可以在归并排序的过程中计算每个元素右侧的元素中与当前元素形成逆序对的元素个数。

考虑下标范围 [ low , high ] [\textit{low}, \textit{high}] [low,high] 的子数组的归并排序过程。当 low ≥ high \textit{low} \ge \textit{high} lowhigh 时,子数组的长度是 0 0 0 1 1 1,此时子数组已经符合升序。当 low < high \textit{low} < \textit{high} low<high 时,子数组的长度大于等于 2 2 2,归并排序的过程为将子数组分成两个更短的子数组,两个更短的子数组排序之后合并,具体过程如下。

  1. low \textit{low} low high \textit{high} high 的平均值 mid \textit{mid} mid,将下标范围 [ low , high ] [\textit{low}, \textit{high}] [low,high] 的子数组分成下标范围 [ low , mid ] [\textit{low}, \textit{mid}] [low,mid] 和下标范围 [ mid + 1 , high ] [\textit{mid} + 1, \textit{high}] [mid+1,high] 的两个子数组。

  2. 将下标范围 [ low , mid ] [\textit{low}, \textit{mid}] [low,mid] 和下标范围 [ mid + 1 , high ] [\textit{mid} + 1, \textit{high}] [mid+1,high] 的两个子数组分别排序,得到两个升序子数组。

  3. i i i j j j 分别表示下标范围 [ low , mid ] [\textit{low}, \textit{mid}] [low,mid] 和下标范围 [ mid + 1 , high ] [\textit{mid} + 1, \textit{high}] [mid+1,high] 的两个升序子数组中的待合并元素下标,初始时 i = low i = \textit{low} i=low j = mid + 1 j = \textit{mid} + 1 j=mid+1。当 i ≤ mid i \le \textit{mid} imid j ≤ high j \le \textit{high} jhigh 时,按照如下操作合并两个子数组,合并过程中需要保持排序的稳定性。

    • 如果 nums [ i ] ≤ nums [ j ] \textit{nums}[i] \le \textit{nums}[j] nums[i]nums[j],则将 nums [ i ] \textit{nums}[i] nums[i] 添加到合并后的结果中,然后将 i i i 1 1 1

    • 如果 nums [ i ] > nums [ j ] \textit{nums}[i] > \textit{nums}[j] nums[i]>nums[j],则将 nums [ j ] \textit{nums}[j] nums[j] 添加到合并后的结果中,然后将 j j j 1 1 1

  4. 当其中一个升序子数组的元素全部合并结束之后,将另一个升序子数组的元素依次添加到合并后的结果中。

由于合并过程保持排序的稳定性,因此当 nums [ i ] ≤ nums [ j ] \textit{nums}[i] \le \textit{nums}[j] nums[i]nums[j] 或者 j = high + 1 j = \textit{high} + 1 j=high+1 时,一定有 nums [ i ] > nums [ j − 1 ] \textit{nums}[i] > \textit{nums}[j - 1] nums[i]>nums[j1](如果 j = high + 1 j = \textit{high} + 1 j=high+1,则有 j − 1 = high j - 1 = \textit{high} j1=high),否则 nums [ i ] = nums [ j − 1 ] \textit{nums}[i] = \textit{nums}[j - 1] nums[i]=nums[j1],在合并 nums [ i ] \textit{nums}[i] nums[i] 之前合并 nums [ j − 1 ] \textit{nums}[j - 1] nums[j1] 与归并排序的稳定性矛盾。因此对于任意 mid + 1 ≤ k ≤ j − 1 \textit{mid} + 1 \le k \le j - 1 mid+1kj1 都有 nums [ i ] > nums [ k ] \textit{nums}[i] > \textit{nums}[k] nums[i]>nums[k],即在下标范围 [ mid + 1 , high ] [\textit{mid} + 1, \textit{high}] [mid+1,high] 的升序子数组中有 j − mid − 1 j - \textit{mid} - 1 jmid1 个数小于 nums [ i ] \textit{nums}[i] nums[i],将 j − mid − 1 j - \textit{mid} - 1 jmid1 加到 nums [ i ] \textit{nums}[i] nums[i] 对应的计数中。

为了记录每个元素右侧小于当前元素的个数,需要维护下标数组和计数数组,在归并排序计算逆序对的过程中同时对原数组和下标数组执行归并操作,确保原数组和下标数组中的每个元素分别对应。当更新一个元素对应的计数时,从下标数组得到该元素的下标,更新计数数组中该下标处的计数。

当整个数组排序结束时,计数数组即为每个元素右侧小于当前元素的个数。

由于计算每个元素的逆序对数量以及合并两个升序子数组都需要遍历两个升序子数组,因此计算每个元素的逆序对数量并没有提升总时间复杂度,总时间复杂度和原始归并排序一样是 O ( n log ⁡ n ) O(n \log n) O(nlogn)

归并排序可以使用自顶向下的方式递归实现,也可以使用自底向上的方式迭代实现。对于同一个数组,使用自顶向下和自底向上两种方式实现的中间过程可能有所区别,但是都能得到正确的结果。

代码

以下代码为归并排序的自顶向下实现。

class Solution {public List<Integer> countSmaller(int[] nums) {int length = nums.length;int[] indices = new int[length];for (int i = 0; i < length; i++) {indices[i] = i;}List<Integer> counts = new ArrayList<Integer>();for (int i = 0; i < length; i++) {counts.add(0);}mergeSortAndCount(nums, indices, counts, 0, length - 1);return counts;}public void mergeSortAndCount(int[] nums, int[] indices, List<Integer> counts, int low, int high) {if (low >= high) {return;}int mid = low + (high - low) / 2;mergeSortAndCount(nums, indices, counts, low, mid);mergeSortAndCount(nums, indices, counts, mid + 1, high);merge(nums, indices, counts, low, mid, high);}public void merge(int[] nums, int[] indices, List<Integer> counts, int low, int mid, int high) {int currLength = high - low + 1;int[] tempNums = new int[currLength];int[] tempIndices = new int[currLength];int i = low, j = mid + 1, k = 0;while (i <= mid && j <= high) {if (nums[i] <= nums[j]) {tempNums[k] = nums[i];tempIndices[k] = indices[i];counts.set(indices[i], counts.get(indices[i]) + (j - mid - 1));i++;} else {tempNums[k] = nums[j];tempIndices[k] = indices[j];j++;}k++;}while (i <= mid) {tempNums[k] = nums[i];tempIndices[k] = indices[i];counts.set(indices[i], counts.get(indices[i]) + (j - mid - 1));i++;k++;}while (j <= high) {tempNums[k] = nums[j];tempIndices[k] = indices[j];j++;k++;}System.arraycopy(tempNums, 0, nums, low, currLength);System.arraycopy(tempIndices, 0, indices, low, currLength);}
}

以下代码为归并排序的自底向上实现。

class Solution {public List<Integer> countSmaller(int[] nums) {int length = nums.length;int[] indices = new int[length];for (int i = 0; i < length; i++) {indices[i] = i;}List<Integer> counts = new ArrayList<Integer>();for (int i = 0; i < length; i++) {counts.add(0);}for (int halfLength = 1, currLength = 2; halfLength < length; halfLength *= 2, currLength *= 2) {for (int low = 0; low < length - halfLength; low += currLength) {int mid = low + halfLength - 1;int high = Math.min(low + currLength - 1, length - 1);merge(nums, indices, counts, low, mid, high);}}return counts;}public void merge(int[] nums, int[] indices, List<Integer> counts, int low, int mid, int high) {int currLength = high - low + 1;int[] tempNums = new int[currLength];int[] tempIndices = new int[currLength];int i = low, j = mid + 1, k = 0;while (i <= mid && j <= high) {if (nums[i] <= nums[j]) {tempNums[k] = nums[i];tempIndices[k] = indices[i];counts.set(indices[i], counts.get(indices[i]) + (j - mid - 1));i++;} else {tempNums[k] = nums[j];tempIndices[k] = indices[j];j++;}k++;}while (i <= mid) {tempNums[k] = nums[i];tempIndices[k] = indices[i];counts.set(indices[i], counts.get(indices[i]) + (j - mid - 1));i++;k++;}while (j <= high) {tempNums[k] = nums[j];tempIndices[k] = indices[j];j++;k++;}System.arraycopy(tempNums, 0, nums, low, currLength);System.arraycopy(tempIndices, 0, indices, low, currLength);}
}

复杂度分析

  • 时间复杂度: O ( n log ⁡ n ) O(n \log n) O(nlogn),其中 n n n 是数组 nums \textit{nums} nums 的长度。归并排序的时间复杂度是 O ( n log ⁡ n ) O(n \log n) O(nlogn)

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums \textit{nums} nums 的长度。下标数组需要 O ( n ) O(n) O(n) 的空间,自顶向下实现时需要递归调用栈的空间是 O ( log ⁡ n ) O(\log n) O(logn),自底向上实现时可以省略递归调用栈的空间。无论是自顶向下实现还是自底向上实现,归并过程需要 O ( n ) O(n) O(n) 的辅助空间。

解法二

预备知识

该解法涉及到线段树。线段树是一种二叉搜索树,将一个区间划分成两个更短的区间。线段树中的每个叶结点都是长度为 1 1 1 的区间,称为单元区间。

线段树支持区间的快速查询和修改。对于长度为 n n n 的区间,使用线段树查询特定子区间的元素个数以及修改特定子区间内的元素个数的时间是 O ( log ⁡ n ) O(\log n) O(logn)

有时,为了降低线段树的空间复杂度,需要使用离散化。

思路和算法

对于长度为 n n n 的数组,其中不同元素的个数最多有 n n n 个。由于计算逆序对数量只需要考虑元素的相对大小,因此可以使用离散化将区间长度限制在 n n n 以内。离散化的方法是计算数组 nums \textit{nums} nums 中的每个元素的名次,计算名次的方法是:新建数组 sorted \textit{sorted} sorted 并将数组 nums \textit{nums} nums 中的所有元素复制到数组 sorted \textit{sorted} sorted 中,然后对数组 sorted \textit{sorted} sorted 排序,排序之后, sorted [ i ] \textit{sorted}[i] sorted[i] 的名次为 i i i,如果 i > 0 i > 0 i>0 sorted [ i ] = sorted [ i − 1 ] \textit{sorted}[i] = \textit{sorted}[i - 1] sorted[i]=sorted[i1] sorted [ i ] \textit{sorted}[i] sorted[i] 的名次与 sorted [ i − 1 ] \textit{sorted}[i - 1] sorted[i1] 的名次相同。每个元素的名次都在范围 [ 0 , n − 1 ] [0, n - 1] [0,n1] 中,表示数组中的小于该元素的元素个数。

由于这道题要求计算每个元素右侧的元素中与当前元素形成逆序对的元素个数,因此遍历数组 nums \textit{nums} nums 的过程中需要确保每个元素右侧的元素已经遍历过,需要从右到左遍历数组 nums \textit{nums} nums 计算逆序对的数量。

创建线段树,用于存储数组 nums \textit{nums} nums 中的每个元素的名次。从右到遍历数组 nums \textit{nums} nums,对于每个元素 num \textit{num} num,其右侧的元素已经遍历过,其右侧的元素中的每个小于 num \textit{num} num 的元素都与 num \textit{num} num 组成一个逆序对,因此得到 num \textit{num} num 的名次 rank \textit{rank} rank,计算线段树的子区间 [ 0 , rank − 1 ] [0, \textit{rank} - 1] [0,rank1] 中的元素个数,该元素个数即为当前元素 num \textit{num} num 元素右侧小于 num \textit{num} num 的元素个数。得到当前元素右侧小于当前元素的个数之后,将 rank \textit{rank} rank 添加到线段树中,继续向左遍历元素并计算每个元素右侧小于当前元素的个数。遍历结束之后,即可得到数组 nums \textit{nums} nums 中的每个元素右侧小于当前元素的个数。

代码

class Solution {public List<Integer> countSmaller(int[] nums) {List<Integer> counts = new ArrayList<Integer>();int length = nums.length;for (int i = 0; i < length; i++) {counts.add(0);}Map<Integer, Integer> ranks = getRanks(nums);SegmentTree st = new SegmentTree(length);for (int i = length - 1; i >= 0; i--) {int rank = ranks.get(nums[i]);counts.set(i, st.getCount(0, rank - 1));st.add(rank);}return counts;}public Map<Integer, Integer> getRanks(int[] nums) {int length = nums.length;int[] sorted = new int[length];System.arraycopy(nums, 0, sorted, 0, length);Arrays.sort(sorted);Map<Integer, Integer> ranks = new HashMap<Integer, Integer>();for (int i = 0; i < length; i++) {int num = sorted[i];if (i == 0 || num > sorted[i - 1]) {ranks.put(num, i);}}return ranks;}
}class SegmentTree {int length;int[] tree;public SegmentTree(int length) {this.length = length;this.tree = new int[length * 4];}public int getCount(int start, int end) {return getCount(start, end, 0, 0, length - 1);}public void add(int rank) {add(rank, 0, 0, length - 1);}private int getCount(int rangeStart, int rangeEnd, int index, int treeStart, int treeEnd) {if (rangeStart > rangeEnd) {return 0;}if (rangeStart == treeStart && rangeEnd == treeEnd) {return tree[index];}int mid = treeStart + (treeEnd - treeStart) / 2;if (rangeEnd <= mid) {return getCount(rangeStart, rangeEnd, index * 2 + 1, treeStart, mid);} else if (rangeStart > mid) {return getCount(rangeStart, rangeEnd, index * 2 + 2, mid + 1, treeEnd);} else {return getCount(rangeStart, mid, index * 2 + 1, treeStart, mid) + getCount(mid + 1, rangeEnd, index * 2 + 2, mid + 1, treeEnd);}}private void add(int rank, int index, int start, int end) {if (start == end) {tree[index]++;return;}int mid = start + (end - start) / 2;if (rank <= mid) {add(rank, index * 2 + 1, start, mid);} else {add(rank, index * 2 + 2, mid + 1, end);}tree[index] = tree[index * 2 + 1] + tree[index * 2 + 2];}
}

复杂度分析

  • 时间复杂度: O ( n log ⁡ n ) O(n \log n) O(nlogn),其中 n n n 是数组 nums \textit{nums} nums 的长度。每个元素在线段树中的查询和更新操作都需要 O ( log ⁡ n ) O(\log n) O(logn) 的时间,时间复杂度是 O ( n log ⁡ n ) O(n \log n) O(nlogn)

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums \textit{nums} nums 的长度。创建线段树需要 O ( n ) O(n) O(n) 的空间。

解法三

预备知识

该解法涉及到树状数组。树状数组也称二叉索引树,由 Peter M. Fenwick 发明,因此又称 Fenwick 树。树状数组支持快速计算数组的前缀和与区间和,以及快速修改。对于长度为 n n n 的区间,使用树状数组查询特定子区间的区间和以及修改特定子区间内的元素值的时间是 O ( log ⁡ n ) O(\log n) O(logn)

有时,为了降低树状数组的空间复杂度,需要使用离散化。

思路和算法

计算每个元素右侧小于当前元素的个数也可以使用树状数组实现。

首先使用离散化将区间长度限制在 n n n 以内,然后创建树状数组,用于存储数组 nums \textit{nums} nums 中的每个元素的名次。从右到左遍历数组 nums \textit{nums} nums,对于每个元素 num \textit{num} num,得到 num \textit{num} num 的名次 rank \textit{rank} rank,计算树状数组的子区间 [ 0 , rank + 1 ] [0, \textit{rank} + 1] [0,rank+1] 中的元素个数,该元素个数即为即为当前元素 num \textit{num} num 元素右侧小于 num \textit{num} num 的元素个数。得到当前元素右侧小于当前元素的个数之后,将 rank \textit{rank} rank 添加到树状数组中,继续向左遍历元素并计算每个元素右侧小于当前元素的个数。遍历结束之后,即可得到数组 nums \textit{nums} nums 中的每个元素右侧小于当前元素的个数。

代码

class Solution {public List<Integer> countSmaller(int[] nums) {List<Integer> counts = new ArrayList<Integer>();int length = nums.length;for (int i = 0; i < length; i++) {counts.add(0);}Map<Integer, Integer> ranks = getRanks(nums);BinaryIndexedTree bit = new BinaryIndexedTree(length);for (int i = length - 1; i >= 0; i--) {int rank = ranks.get(nums[i]);counts.set(i, bit.getCount(0, rank - 1));bit.add(rank);}return counts;}public Map<Integer, Integer> getRanks(int[] nums) {int length = nums.length;int[] sorted = new int[length];System.arraycopy(nums, 0, sorted, 0, length);Arrays.sort(sorted);Map<Integer, Integer> ranks = new HashMap<Integer, Integer>();for (int i = 0; i < length; i++) {int num = sorted[i];if (i == 0 || num > sorted[i - 1]) {ranks.put(num, i);}}return ranks;}
}class BinaryIndexedTree {int length;int[] tree;public BinaryIndexedTree(int length) {this.length = length;this.tree = new int[length + 1];}public int getCount(int start, int end) {return getPrefixSum(end + 1) - getPrefixSum(start);}public void add(int index) {index++;while (index <= length) {tree[index]++;index += lowbit(index);}}private int getPrefixSum(int index) {int sum = 0;while (index > 0) {sum += tree[index];index -= lowbit(index);}return sum;}private static int lowbit(int x) {return x & (-x);}
}

复杂度分析

  • 时间复杂度: O ( n log ⁡ n ) O(n \log n) O(nlogn),其中 n n n 是数组 nums \textit{nums} nums 的长度。每个元素在树状数组中的查询和更新操作都需要 O ( log ⁡ n ) O(\log n) O(logn) 的时间,时间复杂度是 O ( n log ⁡ n ) O(n \log n) O(nlogn)

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums \textit{nums} nums 的长度。创建树状数组需要 O ( n ) O(n) O(n) 的空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1560007.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

前端开发攻略---分块加载大数据

一、问题 解决当遇到较大的数据请求&#xff0c;当用户网络较差的时候&#xff0c;需要等很久很久才能拿到服务器的响应结果&#xff0c;如果这个响应结果需要再页面上展示的话&#xff0c;会导致页面长时间白屏的问题 二、实现原理 当发送一个请求时&#xff0c;需要等服务器把…

照片相册SDK解决方案,模板化包装,简化视频制作流程

专业的视频制作往往门槛较高&#xff0c;让许多用户望而却步&#xff0c;美摄科技推出了全新的照片相册SDK解决方案&#xff0c;旨在通过模板化包装方式&#xff0c;让用户轻松上传照片&#xff0c;快速生成一个充满创意和个性化的照片视频&#xff0c;让每个人都能成为自己生活…

Java的TCP通信

Java的TCP通信 TCP发送数据 Java中的TCP通信 Java对基于TCP协议的的网络提供了良好的封装&#xff0c;使用Socket对象来代表两端的通信端口&#xff0c;并通过Socket产生IO流来进行网络通信。Java为客户端提供了Socket类&#xff0c;为服务器端提供了ServerSocket类 构造方法…

使用 Go 语言与 Elasticsearch 实现高效搜索服务

使用 Go 语言与 Elasticsearch 实现高效搜索服务 什么是 Elasticsearch Elasticsearch 是一个基于 Apache Lucene 构建的分布式搜索引擎&#xff0c;能够存储、搜索和分析大量数据。它具有高可扩展性、快速的搜索速度&#xff0c;支持全文检索、多字段查询和近实时数据分析。…

mysql/doris 计算两个时间相差n天n时n分示范

mysql/doris 计算两个时间相差n天n时n分示范 两个时间&#xff1a;so.create_time&#xff0c;so.update_time CONCAT(FLOOR(DATEDIFF(HOUR ,so.create_time,so.update_time)/24),天,DATEDIFF(HOUR ,so.create_time,so.update_time)%24,时,DATEDIFF(MINUTE ,so.create_time,so…

自动猫砂盆“智商税”还是“真香”?2024自动猫砂盆保姆级干货

平时忙着上班&#xff0c;或者一遇到出差就要离家四五天&#xff0c;没办法给毛孩子的猫砂盆铲屎&#xff0c;导致粪便堆积太久。很多铲屎官也了解到有自动猫砂盆这种东西&#xff0c;但是生怕是智商税&#xff0c;总觉得忍忍手铲也可以&#xff0c;要知道&#xff0c;猫咪的便…

如何在阿里云一键部署FlowiseAI

什么是FlowiseAI FlowiseAI 是一个开源的低代码开发工具&#xff0c;专为开发者构建定制的语言学习模型&#xff08;LLM&#xff09;应用而设计。 通过其拖放式界面&#xff0c;用户可以轻松创建和管理AI驱动的交互式应用&#xff0c;如聊天机器人和数据分析工具。 它基于Lang…

网络安全-Morpheus

NVIDIA Morpheus 文章目录 前言一、简介1. NVIDIA Morpheus 是什么?二、优势1. 深入了解 NVIDIA Morpheus 的优势高管借助全面的数据可见性,实时检测威胁利用生成式 AI 提高效率提升性能,降低成本开发者轻松开发和部署功能丰富,灵活性强实时遥测三、用例Morpheus 用例四、A…

通过观测云 DataKit Extension 接入 AWS Lambda 最佳实践

前言 AWS Lambda 是一项计算服务&#xff0c;使用时无需预配置或管理服务器即可运行代码。AWS Lambda 只在需要时执行代码并自动缩放。借助 AWS Lambda&#xff0c;几乎可以为任何类型的应用程序或后端服务运行代码&#xff0c;而且无需执行任何管理。 Lambda Layer 是一个包…

AI绘画,AI生成图片

分享一个可以免费使用的AI生成图片的网站&#xff1a; https://openart.aihttps://openart.ai/create 1、登陆后点击右上角create 2、在创建页面左侧输入描述文案&#xff0c;下面调整生成图片张数&#xff0c;点击create&#xff0c;右边即可生成 我这里输入了在吃麦当劳的超…

笔记||VUE3

侦听器 | Vue.js (vuejs.org) 模板引用 | Vue.js (vuejs.org)

Java初阶~~四种内部类总结

文章目录 1.内部类的分类2.局部内部类2.1.基本语法2.2就近原则的理解 3.匿名内部类3.1基于接口的匿名内部类3.2基于普通类的匿名内部类3.3基于抽象类的匿名内部类3.4匿名内部类的细节3.5匿名内部类实践3.5.1作为实参进行传递3.5.2实践案例 4.成员内部类4.1基本介绍4.2外部类&am…

api测试和接口测试的区别

API测试和接口测试是软件测试中一个非常重要的领域&#xff0c;尤其是在当前Web应用程序和移动应用程序的发展中。虽然它们都测试了Web服务的功能&#xff0c;但是二者在测试方法和测试实施方面存在很大的差异。本文将介绍API测试和接口测试之间的主要区别 API测试的主要关注点…

【LLM论文日更】| BGE经典论文-CPACK

论文&#xff1a;https://arxiv.org/pdf/2309.07597代码&#xff1a;GitHub - FlagOpen/FlagEmbedding: Retrieval and Retrieval-augmented LLMs机构&#xff1a;BAAI领域&#xff1a;embedding model发表&#xff1a;SIGIR 2024 ​ 研究背景 研究问题&#xff1a;这篇文章…

MySQL插入优化-性能对比

插入优化主要包括&#xff1a; 批量插入条数据&#xff0c;而不是单个记录逐条插入。手动提交事务&#xff0c;避免自动提交事务带来的额外开销。使用load命令从本地文件导入。 性能对比 创建数据库表 CREATE TABLE if not exists tb_sku ( id int(20) …

防汛可视化系统:提升应急响应能力

通过图扑可视化系统实时监测水情、雨情和地理数据&#xff0c;辅助防汛决策与调度&#xff0c;提供直观的风险预警信息&#xff0c;从而优化资源分配&#xff0c;提高防汛应急响应效率。

​​​​​​​如何使用LTX Studio生成故事插画

在这个科技飞速发展的时代&#xff0c;人工智能已经成为创意领域的重要工具。LTX Studio 是一个强大的平台&#xff0c;可以帮助你将文字故事生成精美的插画。以下是详细的步骤&#xff0c;教你如何使用LTX Studio 生成故事插画。 生成prompt、&#xff1a; 使用copilot实现&…

SD2.0 Specification之SD卡寄存器(Card Register)

文章目录 CID(Card IDentification)RCA(Relative Card Address)DSR(Driver Stage Register)CSD(Card-Specific Data)SCR(SD CARD Configuration Register)OCR(Operation Conditions Register)SSR(SD Status Register)CSR(Card Status Register) 本文章主要讲解SD2.0的各个卡寄存…

望繁信科技成功签约国显科技 流程挖掘助力制造业智造未来

近日&#xff0c;上海望繁信科技有限公司&#xff08;简称“望繁信科技”&#xff09;成功与深圳市国显科技有限公司&#xff08;简称“国显科技”&#xff09;达成合作。国显科技作为全球领先的TFT-LCD液晶显示及Mini/Micro LED显示产品供应商&#xff0c;致力于为笔记本、手机…

Linux云计算 |【第四阶段】RDBMS2-DAY4

主要内容&#xff1a; MHA概述、部署MHA集群 一、MHA概述 1、MHA简介 MHA&#xff08;Master High Availability&#xff09;是一款开源的MySQL的高可用程序&#xff0c;由日本DeNA公司youshimaton开发&#xff0c;是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的…