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

Java详解LeetCode 热题 100(15):LeetCode 189. 轮转数组(Rotate Array)详解

文章目录

    • 1. 题目描述
    • 2. 理解题目
    • 3. 解法一:使用额外数组
      • 3.1 思路
      • 3.2 Java代码实现
      • 3.3 代码详解
      • 3.4 复杂度分析
      • 3.5 适用场景
    • 4. 解法二:环状替换法(原地算法)
      • 4.1 思路
      • 4.2 Java代码实现
      • 4.3 代码详解
      • 4.4 复杂度分析
      • 4.5 陷阱与注意事项
    • 5. 解法三:数组翻转法(最优原地算法)
      • 5.1 思路
      • 5.2 Java代码实现
      • 5.3 代码详解
      • 5.4 数学证明
      • 5.5 复杂度分析
      • 5.6 适用场景
    • 6. 详细步骤分析与示例跟踪
      • 6.1 示例跟踪:使用额外数组法
      • 6.2 示例跟踪:环状替换法
      • 6.3 示例跟踪:数组翻转法
    • 7. 常见错误与优化
      • 7.1 常见错误
      • 7.2 优化技巧
    • 8. 三种解法的对比与选择
    • 9. 扩展题目与应用
      • 9.1. 左轮转数组
      • 9.2. 字符串轮转
      • 9.3. 循环移位操作
    • 10. 实际应用场景
    • 11. 完整的 Java 解决方案
    • 12. 总结与技巧
      • 12.1 解题要点
      • 12.2 学习收获
      • 12.3 面试技巧
    • 13. 参考资料

1. 题目描述

给你一个数组,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

示例 1:

输入: nums = [1,2,3,4,5,6,7], k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右轮转 1 步: [7,1,2,3,4,5,6]
向右轮转 2 步: [6,7,1,2,3,4,5]
向右轮转 3 步: [5,6,7,1,2,3,4]

示例 2:

输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释: 
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]

提示:

  • 1 <= nums.length <= 10^5
  • -2^31 <= nums[i] <= 2^31 - 1
  • 0 <= k <= 10^5

进阶:

  • 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
  • 你可以使用空间复杂度为 O(1) 的 原地 算法解决这个问题吗?

2. 理解题目

这道题要求我们将数组中的所有元素向右移动k个位置。具体来说:

  • 数组中的每个元素都向右移动k个索引位置
  • 数组是"循环"的,即超出数组末尾的元素会被放置到数组的开头
  • 我们需要原地修改数组,而不是创建一个新数组(尽管也可以使用额外空间的解法)

关键点:

  1. k可能大于数组长度,因此实际的移动次数是k % n(其中n是数组长度)
  2. 向右轮转k次等同于将数组最后k个元素移动到数组开头
  3. 这道题可以有多种解法,包括使用额外空间和原地(O(1)空间复杂度)算法

3. 解法一:使用额外数组

3.1 思路

最简单直观的方法是创建一个新数组,然后将原数组的每个元素放到新数组中的正确位置:

  1. 创建一个与原数组相同大小的新数组
  2. 对于原数组中索引为i的元素,其在新数组中的位置为(i + k) % n
  3. 将新数组的内容复制回原数组

这种方法使用了O(n)的额外空间,但思路非常清晰,适合初学者理解。

3.2 Java代码实现

class Solution {public void rotate(int[] nums, int k) {int n = nums.length;// 处理 k 大于数组长度的情况k = k % n;// 如果k为0,不需要轮转if (k == 0) {return;}// 创建一个新数组来存储轮转后的结果int[] result = new int[n];// 将原数组中的元素放入新数组的正确位置for (int i = 0; i < n; i++) {result[(i + k) % n] = nums[i];}// 将新数组的内容复制回原数组for (int i = 0; i < n; i++) {nums[i] = result[i];}}
}

3.3 代码详解

详细解释每一步的意义和实现:

int n = nums.length;// 处理 k 大于数组长度的情况
k = k % n;// 如果k为0,不需要轮转
if (k == 0) {return;
}
  • 首先获取数组长度n
  • 由于轮转n次会回到原始状态,所以我们只需要考虑k % n次轮转
  • 如果k为0或者k是n的倍数,数组不需要变化,直接返回
// 创建一个新数组来存储轮转后的结果
int[] result = new int[n];// 将原数组中的元素放入新数组的正确位置
for (int i = 0; i < n; i++) {result[(i + k) % n] = nums[i];
}
  • 创建一个与原数组相同大小的新数组
  • 将原数组中索引为i的元素放到新数组中索引为(i + k) % n的位置
  • 这里使用模运算是为了处理索引超出数组长度的情况
// 将新数组的内容复制回原数组
for (int i = 0; i < n; i++) {nums[i] = result[i];
}
  • 最后,将临时数组中的结果复制回原数组,完成轮转操作

3.4 复杂度分析

  • 时间复杂度: O(n),其中n是数组的长度。我们需要遍历数组两次,每次遍历的时间复杂度是O(n)。
  • 空间复杂度: O(n),我们创建了一个与原数组等长的新数组。

3.5 适用场景

这种解法适用于:

  • 初学者理解问题
  • 代码简洁性优先于空间效率的场景
  • 数组不太大的情况

4. 解法二:环状替换法(原地算法)

4.1 思路

我们可以直接在原数组上进行操作,不使用额外空间。基本思想是:

  1. 从位置0开始,将当前位置的元素放到它应该去的位置(即(i + k) % n),同时记录被替换的元素
  2. 然后将被替换的元素放到它应该去的位置,继续这个过程
  3. 当我们回到起始位置时,我们已经完成了一个循环,需要从下一个位置开始新的循环
  4. 重复这个过程,直到所有元素都被访问

这种方法不使用额外数组,但需要仔细处理访问元素的顺序。

4.2 Java代码实现

class Solution {public void rotate(int[] nums, int k) {int n = nums.length;k = k % n;// 如果k为0,不需要轮转if (k == 0) {return;}int count = 0; // 记录已经移动的元素数量// 从0开始,最多需要处理n个元素for (int start = 0; count < n; start++) {int current = start; // 当前处理的位置int prev = nums[start]; // 当前位置的值do {// 计算下一个位置int next = (current + k) % n;// 保存下一个位置的值int temp = nums[next];// 将当前值放到下一个位置nums[next] = prev;// 更新current和prev,继续下一次替换current = next;prev = temp;count++;} while (start != current); // 当回到起始位置时,一个循环结束}}
}

4.3 代码详解

环状替换的关键在于追踪元素的移动路径,确保每个元素都被移动到正确位置:

int count = 0; // 记录已经移动的元素数量// 从0开始,最多需要处理n个元素
for (int start = 0; count < n; start++) {int current = start; // 当前处理的位置int prev = nums[start]; // 当前位置的值
  • count变量记录我们已经处理过的元素数量
  • start表示当前循环的起始位置
  • current跟踪我们当前正在处理的位置
  • prev存储当前位置原来的值
do {// 计算下一个位置int next = (current + k) % n;// 保存下一个位置的值int temp = nums[next];// 将当前值放到下一个位置nums[next] = prev;// 更新current和prev,继续下一次替换current = next;prev = temp;count++;
} while (start != current); // 当回到起始位置时,一个循环结束
  • 计算元素应该被放置的下一个位置:(current + k) % n
  • 在替换前,保存目标位置的原始值
  • 将当前值放到目标位置
  • 更新current为新位置,prev为新位置原来的值
  • 增加已处理元素计数
  • 重复此过程,直到回到循环的起始位置

当一个循环结束(回到起始位置)时,可能还有未被访问的元素。因此,我们增加start并开始一个新的循环,直到所有元素都被处理。

4.4 复杂度分析

  • 时间复杂度: O(n),每个元素只会被移动一次,总共需要移动n次。
  • 空间复杂度: O(1),只使用了有限的几个变量,不需要额外数组。

4.5 陷阱与注意事项

环状替换法需要特别注意:

  1. 处理循环长度:如果k和n有公约数,一个循环结束后可能还有元素未被访问,需要开始新的循环
  2. 边界条件:确保我们处理了所有的元素(通过计数)
  3. 避免原地自我覆盖:在移动元素前保存下一个位置的值

5. 解法三:数组翻转法(最优原地算法)

5.1 思路

这是最优雅且高效的解法。基本思想是:

  1. 首先翻转整个数组
  2. 然后翻转前k个元素
  3. 最后翻转剩余的n-k个元素

这种方法不需要额外空间,操作简单明了,且易于实现。

5.2 Java代码实现

class Solution {public void rotate(int[] nums, int k) {int n = nums.length;k = k % n;// 如果k为0,不需要轮转if (k == 0) {return;}// 1. 翻转整个数组reverse(nums, 0, n - 1);// 2. 翻转前k个元素reverse(nums, 0, k - 1);// 3. 翻转剩余的n-k个元素reverse(nums, k, n - 1);}// 辅助函数:翻转数组的指定部分private void reverse(int[] nums, int start, int end) {while (start < end) {int temp = nums[start];nums[start] = nums[end];nums[end] = temp;start++;end--;}}
}

5.3 代码详解

数组翻转法的优雅之处在于它非常直观:

// 1. 翻转整个数组
reverse(nums, 0, n - 1);
  • 首先将整个数组翻转,这样原来的顺序就变成了逆序
  • 例如:[1,2,3,4,5,6,7] 变成 [7,6,5,4,3,2,1]
// 2. 翻转前k个元素
reverse(nums, 0, k - 1);
  • 然后翻转前k个元素,将这部分恢复正确的相对顺序
  • 对于k=3,[7,6,5,4,3,2,1] 的前k个元素 [7,6,5] 翻转后变成 [5,6,7,4,3,2,1]
// 3. 翻转剩余的n-k个元素
reverse(nums, k, n - 1);
  • 最后翻转剩余的n-k个元素,将这部分也恢复正确的相对顺序
  • [5,6,7,4,3,2,1] 的后n-k个元素 [4,3,2,1] 翻转后变成 [5,6,7,1,2,3,4]
  • 这就是最终的轮转结果
// 辅助函数:翻转数组的指定部分
private void reverse(int[] nums, int start, int end) {while (start < end) {int temp = nums[start];nums[start] = nums[end];nums[end] = temp;start++;end--;}
}
  • 辅助函数实现了数组特定范围内的翻转
  • 使用双指针法,从两端向中间逐步交换元素
  • 这是一个标准的数组翻转操作

5.4 数学证明

为什么数组翻转法能实现轮转效果?我们可以从数学角度证明:

设原数组为A,长度为n,需要右移k个位置。

  1. 定义A’ = A[0…n-k-1],表示原数组的前n-k个元素
  2. 定义A’’ = A[n-k…n-1],表示原数组的后k个元素
  3. 原数组可表示为:A = [A’, A’']
  4. 向右轮转k个位置后的数组为:B = [A’‘, A’]

数组翻转法的步骤:

  1. 翻转整个数组:[A’, A’‘] → [(A’‘)^r, (A’)r],其中r表示翻转
  2. 翻转前k个元素:[(A’‘)^r, (A’)^r] → [A’‘, (A’)^r]
  3. 翻转后n-k个元素:[A’‘, (A’)^r] → [A’‘, A’]

最终结果:[A’‘, A’],这正是轮转后的结果。

5.5 复杂度分析

  • 时间复杂度: O(n),翻转数组需要O(n)的时间。
  • 空间复杂度: O(1),只使用了有限的临时变量。

5.6 适用场景

数组翻转法因其简洁性和效率,几乎适用于所有场景:

  • 需要原地操作的场景
  • 性能要求高的场景
  • 代码简洁度要求高的场景

6. 详细步骤分析与示例跟踪

让我们通过一个具体例子来跟踪每种算法的执行过程,加深理解。

6.1 示例跟踪:使用额外数组法

输入:nums = [1,2,3,4,5,6,7], k = 3

  1. 计算实际轮转次数:k = k % n = 3 % 7 = 3
  2. 创建新数组:result = new int[7]
  3. 将原数组元素放入新数组:
    • nums[0]=1 → result[(0+3)%7]=result[3]=1
    • nums[1]=2 → result[(1+3)%7]=result[4]=2
    • nums[2]=3 → result[(2+3)%7]=result[5]=3
    • nums[3]=4 → result[(3+3)%7]=result[6]=4
    • nums[4]=5 → result[(4+3)%7]=result[0]=5
    • nums[5]=6 → result[(5+3)%7]=result[1]=6
    • nums[6]=7 → result[(6+3)%7]=result[2]=7
  4. 现在result=[5,6,7,1,2,3,4]
  5. 将result复制回nums:nums=[5,6,7,1,2,3,4]

6.2 示例跟踪:环状替换法

输入:nums = [1,2,3,4,5,6,7], k = 3

  1. 计算实际轮转次数:k = k % n = 3 % 7 = 3

  2. 开始从start=0处的环状替换:

    • 当前位置current=0,当前值prev=nums[0]=1
    • 下一个位置next=(0+3)%7=3,保存nums[3]=4
    • 将1放入位置3:nums=[1,2,3,1,5,6,7],current=3,prev=4
    • 下一个位置next=(3+3)%7=6,保存nums[6]=7
    • 将4放入位置6:nums=[1,2,3,1,5,6,4],current=6,prev=7
    • 下一个位置next=(6+3)%7=2,保存nums[2]=3
    • 将7放入位置2:nums=[1,2,7,1,5,6,4],current=2,prev=3
    • 下一个位置next=(2+3)%7=5,保存nums[5]=6
    • 将3放入位置5:nums=[1,2,7,1,5,3,4],current=5,prev=6
    • 下一个位置next=(5+3)%7=1,保存nums[1]=2
    • 将6放入位置1:nums=[1,6,7,1,5,3,4],current=1,prev=2
    • 下一个位置next=(1+3)%7=4,保存nums[4]=5
    • 将2放入位置4:nums=[1,6,7,1,2,3,4],current=4,prev=5
    • 下一个位置next=(4+3)%7=0,保存nums[0]=1
    • 将5放入位置0:nums=[5,6,7,1,2,3,4],current=0,prev=1
    • 现在current=0=start,一个循环结束,且count=7,所有元素都已处理
  3. 最终结果:nums=[5,6,7,1,2,3,4]

6.3 示例跟踪:数组翻转法

输入:nums = [1,2,3,4,5,6,7], k = 3

  1. 计算实际轮转次数:k = k % n = 3 % 7 = 3
  2. 翻转整个数组:
    • nums=[1,2,3,4,5,6,7] → nums=[7,6,5,4,3,2,1]
  3. 翻转前k个元素(前3个):
    • nums=[7,6,5,4,3,2,1] → nums=[5,6,7,4,3,2,1]
  4. 翻转剩余n-k个元素(后4个):
    • nums=[5,6,7,4,3,2,1] → nums=[5,6,7,1,2,3,4]
  5. 最终结果:nums=[5,6,7,1,2,3,4]

7. 常见错误与优化

7.1 常见错误

  1. 忘记处理k大于数组长度的情况

    // 错误:不处理k大于数组长度的情况
    public void rotate(int[] nums, int k) {// k可能大于nums.length,未处理会导致索引越界...
    }// 正确:进行取模操作
    public void rotate(int[] nums, int k) {int n = nums.length;k = k % n; // 确保k在有效范围内...
    }
    
  2. 环状替换中的循环处理错误

    // 错误:处理不完整,可能漏掉某些元素
    public void rotate(int[] nums, int k) {// ...int start = 0;int current = start;int prev = nums[start];// 只进行一个循环,可能无法处理所有元素do {// ...} while (start != current);
    }// 正确:确保处理所有元素
    public void rotate(int[] nums, int k) {// ...int count = 0;for (int start = 0; count < n; start++) {// 确保所有元素都被处理// ...count++;}
    }
    
  3. 数组翻转边界错误

    // 错误:翻转边界不正确
    reverse(nums, 0, k); // 错误,应该是k-1
    reverse(nums, k, n); // 错误,应该是k到n-1// 正确:正确的翻转边界
    reverse(nums, 0, k - 1);
    reverse(nums, k, n - 1);
    

7.2 优化技巧

  1. 提前检查特殊情况

    // 优化:提前处理不需要轮转的情况
    if (k == 0 || k % n == 0) {return; // 不需要轮转
    }
    
  2. 使用Java内置的数组复制方法

    // 优化:使用System.arraycopy替代手动循环复制
    System.arraycopy(result, 0, nums, 0, n);
    
  3. 减少不必要的取模操作

    // 优化前:每次都进行取模
    for (int i = 0; i < n; i++) {result[(i + k) % n] = nums[i];
    }// 优化后:预计算起始位置
    int start = n - k;
    for (int i = 0; i < k; i++) {result[i] = nums[start + i];
    }
    for (int i = 0; i < n - k; i++) {result[k + i] = nums[i];
    }
    
  4. 环状替换中优化循环判断

    // 优化:使用数学方法计算循环次数
    int gcd = gcd(n, k); // 计算n和k的最大公约数// 只需要进行gcd次循环,每次处理n/gcd个元素
    for (int start = 0; start < gcd; start++) {// ...
    }// 辅助方法:计算最大公约数
    private int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);
    }
    

8. 三种解法的对比与选择

解法时间复杂度空间复杂度优点缺点适用场景
额外数组法O(n)O(n)简单直观,容易实现需要额外空间初学者,空间不敏感的场景
环状替换法O(n)O(1)不需要额外空间实现较复杂,需要处理循环空间敏感场景,追求原地操作
数组翻转法O(n)O(1)优雅简洁,不需要额外空间需要理解翻转原理几乎所有场景的最优选择

总结

  • 如果你是初学者或追求代码简洁性,使用额外数组法
  • 如果你需要节省空间且追求性能,使用数组翻转法
  • 环状替换法虽然有趣,但实现复杂,通常不是首选

9. 扩展题目与应用

9.1. 左轮转数组

与本题类似,但方向相反,将数组元素向左移动k个位置。

解决方案:

  • 向左轮转k个位置等同于向右轮转n-k个位置
  • 或者使用相同的数组翻转法,只需调整翻转顺序:
    1. 翻转整个数组
    2. 翻转前n-k个元素
    3. 翻转后k个元素

9.2. 字符串轮转

LeetCode 796. 旋转字符串:检查一个字符串是否可以通过多次轮转变成另一个字符串。

解决思路:将原字符串与自身拼接,如果目标字符串是拼接结果的子串,则可以通过轮转得到。

9.3. 循环移位操作

在计算机系统中,轮转操作常用于循环移位(Circular Shift):

  • 循环左移:将二进制数的最高位移到最低位
  • 循环右移:将二进制数的最低位移到最高位

10. 实际应用场景

轮转数组在实际编程中有多种应用:

  1. 缓冲区管理

    • 实现循环缓冲区时,可以使用轮转数组避免数据移动
    • 在流媒体处理中保持最近的数据片段
  2. 图像处理

    • 图像旋转和变换
    • 图像滤波器的实现
  3. 信号处理

    • 信号采样和处理时的数据轮转
    • FFT算法中的数据重排
  4. 游戏开发

    • 游戏地图的循环移动(如无限地图)
    • 轮流游戏中的玩家顺序管理
  5. 调度算法

    • 轮转调度算法(Round Robin)中任务的轮换
    • 分时系统中的时间片分配

11. 完整的 Java 解决方案

以下是结合了各种最佳实践的最优解法(数组翻转法):

class Solution {public void rotate(int[] nums, int k) {if (nums == null || nums.length <= 1) {return; // 处理边界情况}int n = nums.length;k = k % n; // 处理k大于数组长度的情况if (k == 0) {return; // 不需要轮转}// 三步翻转法reverse(nums, 0, n - 1);   // 翻转整个数组reverse(nums, 0, k - 1);   // 翻转前k个元素reverse(nums, k, n - 1);   // 翻转剩余的n-k个元素}// 翻转数组的指定范围private void reverse(int[] nums, int start, int end) {while (start < end) {int temp = nums[start];nums[start++] = nums[end];nums[end--] = temp;}}
}

这个解法简洁高效,适用于大多数场景。在LeetCode上,这个解法通常能击败95%以上的提交。

12. 总结与技巧

12.1 解题要点

  1. 正确理解轮转:理解轮转的本质是循环移动,超出数组末尾的元素会回到开头。
  2. 取模处理:使用k % n来处理k可能大于数组长度的情况。
  3. 选择合适的算法:根据空间要求选择适当的算法(额外空间法或原地算法)。
  4. 翻转技巧:数组翻转是解决轮转问题的强大工具。

12.2 学习收获

通过学习轮转数组问题,你可以掌握:

  • 原地算法的思想和实现
  • 双指针技术在数组操作中的应用
  • 数学思维在算法设计中的重要性
  • 空间和时间复杂度的权衡

12.3 面试技巧

如果在面试中遇到此类问题:

  1. 先提出最简单的解法(使用额外数组)
  2. 然后提出原地算法(如数组翻转法)
  3. 讨论每种方法的时间和空间复杂度
  4. 分析各种解法的适用场景和优缺点
  5. 实现你认为最优的解法

记住,展示你的思考过程和对不同解法的理解,比仅仅给出一个正确答案更重要。

13. 参考资料

  • LeetCode 官方题解:轮转数组
  • LeetCode 题目链接:轮转数组

相关文章:

Java详解LeetCode 热题 100(15):LeetCode 189. 轮转数组(Rotate Array)详解

文章目录 1. 题目描述2. 理解题目3. 解法一&#xff1a;使用额外数组3.1 思路3.2 Java代码实现3.3 代码详解3.4 复杂度分析3.5 适用场景 4. 解法二&#xff1a;环状替换法&#xff08;原地算法&#xff09;4.1 思路4.2 Java代码实现4.3 代码详解4.4 复杂度分析4.5 陷阱与注意事…...

出于PCB设计层面考虑,连排半孔需要注意哪些事项?

通过拼接作为后处理运行&#xff0c;用拼接联排半孔填充铜的自由区域。为了使通缝成为可能&#xff0c;必须在不同的层上有重叠的铜区域连接到指定的网上。铜的支持区域包括填充、多边形和动力平面。 高电流对电路板的潜在负面影响的另一个例子是电路板结构的物理失效。制造原始…...

JIT+Opcache如何配置才能达到性能最优

首先打开php.ini文件&#xff0c;进行配置 1、OPcache配置 ; 启用OPcache opcache.enable1; CLI环境下启用OPcache&#xff08;按需配置&#xff09; opcache.enable_cli0; 预加载脚本&#xff08;PHP 7.4&#xff0c;加速常用类&#xff09; ; opcache.preload/path/to/prel…...

VR和眼动控制集群机器人的方法

西安建筑科技大学信息与控制工程学院雷小康老师团队联合西北工业大学航海学院彭星光老师团队&#xff0c;基于虚拟现实&#xff08;VR&#xff09;和眼动追踪技术实现了人-集群机器人高效、灵活的交互控制。相关研究论文“基于虚拟现实和眼动的人-集群机器人交互方法” 发表于信…...

LabVIEW与PLC通讯程序S7.Net.dll

下图中展示的是 LabVIEW 环境下通过调用S7.Net.dll 组件与西门子 PLC 进行通讯的程序。LabVIEW 作为一种图形化编程语言&#xff0c;结合S7.Net.dll 的.NET 组件优势&#xff0c;在工业自动化领域中可高效实现与 PLC 的数据交互&#xff0c;快速构建工业监控与控制应用。相较于…...

【华为】现场配置OSPF

原创&#xff1a;厦门微思网络 实验目的 1、了解OSPF的运行原理 2、掌握OSPF的配置方法 实验拓扑 实验需求 1、根据实验拓扑图&#xff0c;完成设备的基本配置&#xff1b; 2、分别在R1、R2、R3上创建Loopback0接口&#xff0c;IP地址分别是1.1.1.1/32、2.2.2.2/32、3.3.3.…...

STM32-DMA数据转运(8)

目录 一、简介 二、存储器映像 三、DMA框图​编辑 四、DMA基本结构 五、两个数据转运的实例 一、简介 直接存储器存取简称DMA&#xff08;Direct Memory Access&#xff09;&#xff0c;它是一个数据转运小助手&#xff0c;主要用来协助CPU&#xff0c;完成数据转运的工作…...

课题推荐——低成本地磁导航入门,附公式推导和MATLAB例程运行演示

地磁导航利用地球磁场的自然特性&#xff0c;通过感知磁场变化&#xff0c;帮助机器人或无人设备实现定位和导航。相比于 GPS、激光雷达等导航方法&#xff0c;地磁导航具有以下优势&#xff1a; 低成本&#xff1a;使用地磁传感器&#xff08;如电子罗盘&#xff09;&#xff…...

微信小程序学习之底部导航栏

首先&#xff0c;我们在app.json中添加4个页面&#xff0c; "pages": ["pages/index/index","pages/category/category","pages/cart/cart","pages/user/user"], 其次我们把8张图片放到imaes文件夹下&#xff0c; 图标可…...

c++ std库中的文件操作学习笔记

1. 概述 C标准库提供了 头文件中的几个类来进行文件操作&#xff0c;这些类封装了底层的文件操作&#xff0c;提供了面向对象和类型安全的接口&#xff0c;使得文件读写更加便捷和高效。主要的文件流类包括&#xff1a; std::ifstream&#xff1a;用于从文件中读取数据。 st…...

多臂赌博机:探索与利用的平衡艺术

1. 引言 在机器学习领域&#xff0c;多臂赌博机&#xff08;Multi-Armed Bandit&#xff0c;MAB&#xff09;问题是强化学习的一个经典且基础的模型。这个名称源于赌场中的"单臂老虎机"&#xff08;One-armed Bandit&#xff09;&#xff0c;因为这种赌博机器像强盗…...

分布式异步强化学习框架训练32B大模型:INTELLECT-2

INTELLECT-2 模型详解 一、模型概述 INTELLECT-2 是一个拥有 320 亿参数的语言模型&#xff0c;其训练采用了一种创新的方式&#xff0c;即通过社区贡献的分布式、无需许可的 GPU 资源进行强化学习训练。该模型基于 qwen2 架构构建&#xff0c;因此与 vllm 或 sglang 等流行库…...

HTML应用指南:利用POST请求获取全国京东快递服务网点位置信息

京东快递作为中国领先的智能供应链与综合物流服务提供商,自2007年成立以来,始终致力于通过技术创新与高效运营,为客户提供安全、可靠、快速的物流解决方案。京东快递依托京东集团的强大资源支持,凭借其自营仓储、干线运输、末端配送一体化的物流网络,在激烈的市场竞争中脱…...

通过POI实现对word基于书签的内容替换、删除、插入

一、基本概念 POI&#xff1a;即Apache POI&#xff0c; 它是一个开源的 Java 库&#xff0c;主要用于读取 Microsoft Office 文档&#xff08;Word、Excel、PowerPoint 等&#xff09;&#xff0c;修改 或 生成 Office 文档内容&#xff0c;保存 为对应的二进制或 XML 格式&a…...

git进行版本控制时遇到Push cannot contain secrets的解决方法

git进行版本控制&#xff0c;push遇到Push cannot contain secrets的解决方法 最近在项目开发过程中&#xff0c;我遇到了一个让我头疼不已的问题。 问题的出现 一开始&#xff0c;我的项目远程仓库连接的是 Gitee&#xff0c;在开发过程中一切都很顺利&#xff0c;我也习惯…...

Java GUI 开发之旅:Swing 组件与布局管理的实战探索

在编程的世界里&#xff0c;图形用户界面&#xff08;GUI&#xff09;设计一直是提升用户体验的关键环节。Java 的 Swing 库为我们提供了强大的工具来构建跨平台的 GUI 应用。今天&#xff0c;我将通过一次实验&#xff0c;分享如何使用 Java Swing 开发一个功能丰富的 GUI 应用…...

OpenVLA (2) 机器人环境和环境数据

文章目录 前言1 BridgeData V21.1 概述1.2 硬件环境 2 数据集2.1 场景与结构2.2 数据结构2.2.1 images02.2.2 obs_dict.pkl2.2.3 policy_out.pkl 前言 按照笔者之前的行业经验, 数据集的整理是非常重要的, 因此笔者这里增加原文中出现的几个数据集和环境的学习 1 BridgeData V…...

【Ansible】基于windows主机,采用NTLM+HTTPS 认证部署

我们现在准备Linux centos7&#xff08;Ansible控制机&#xff09;和Windows&#xff08;客户机&#xff09;环境下的详细部署步骤&#xff1a; 一、Windows客户机配置 1. 准备SSL证书 1.1 生成自签名证书&#xff08;测试用&#xff09; 以管理员身份打开PowerShell&#…...

React19源码系列之 API(react-dom)

API之 preconnect preconnect – React 中文文档 preconnect 函数向浏览器提供一个提示&#xff0c;告诉它应该打开到给定服务器的连接。如果浏览器选择这样做&#xff0c;则可以加快从该服务器加载资源的速度。 preconnect(href) 一、使用例子 import { preconnect } fro…...

鸿蒙Next开发 获取APP缓存大小和清除缓存

1. 鸿蒙Next开发 获取APP缓存大小和清除缓存 1.1. 介绍 1.1.1. 文件系统分类 在最新的Core File Kit套件中&#xff0c;按文件所有者的不同。分为如下三类&#xff1a;   &#xff08;1&#xff09;应用文件&#xff1a;文件所有者为应用&#xff0c;包括应用安装文件、应用…...

PNG转ico图标(支持圆角矩形/方形+透明背景)Python脚本 - 随笔

摘要 在网站开发或应用程序设计中&#xff0c;常需将高品质PNG图像转换为ICO格式图标。本文提供一份基于Pillow库实现的&#xff0c;能够完美保留透明背景且支持导出圆角矩形/方形图标的格式转换脚本。 源码示例 圆角方形 from PIL import Image, ImageDraw, ImageOpsdef c…...

『大模型笔记』Langchain作者Harrison Chase专访:环境智能体与全新智能体收件箱

Langchain作者Harrison Chase专访:环境智能体与全新智能体收件箱 文章目录 摘要访谈内容什么环境智能体为什么要探索环境智能体怎么让人类能更方便地和环境智能体互动参考文献摘要 LangChain 的 CEO Harrison Chase 提出了_“环境智能体”(Ambient Agents)的概念,这是一种…...

GPT( Generative Pre-trained Transformer )模型:基于Transformer

GPT是由openAI开发的一款基于Transformer架构的预训练语言模型&#xff0c;拥有强大的生成能力和多任务处理能力&#xff0c;推动了自然语言处理&#xff08;NLP&#xff09;的快速发展。 一 GPT发展历程 1.1 GPT-1&#xff08;2018年&#xff09; 是首个基于Transformer架构…...

游戏引擎学习第275天:将旋转和剪切传递给渲染器

回顾并为今天的内容定下基调 我们认为在实现通用动画系统之前&#xff0c;先学习如何手写动画逻辑是非常有价值的。虽然加载和播放预设动画是合理的做法&#xff0c;尤其是在团队中有美术人员使用工具制作动画的情况下更是如此&#xff0c;但手动编写动画代码能让我们更深入理…...

conda 输出指定python环境的库 输出为 yaml文件

conda 输出指定python环境的库 输出为 yaml文件。 有时为了项目部署&#xff0c;需要匹配之前的python环境&#xff0c;需要输出对应的python依赖库。 假设你的目标环境名为 myenv&#xff0c;运行以下命令&#xff1a; conda env export -n myenv > myenv_environment.ym…...

ES6 语法

扩展运算符 … 口诀&#xff1a;三个点&#xff0c;打散数组&#xff0c;逐个放进去 例子&#xff1a; let arr [1, 2];let more [3, 4];arr.push(...more); // arr 变成 [1, 2, 3, 4]解构赋值 口诀&#xff1a;左边是变量&#xff0c;右边是值&#xff0c;一一对应 例子&…...

BFS算法篇——打开智慧之门,BFS算法在拓扑排序中的诗意探索(下)

文章目录 引言一、课程表1.1 题目链接&#xff1a;https://leetcode.cn/problems/course-schedule/description/1.2 题目分析&#xff1a;1.3 思路讲解&#xff1a;1.4 代码实现&#xff1a; 二、课程表||2.1 题目链接&#xff1a;https://leetcode.cn/problems/course-schedul…...

While语句数数字

import java.util.Scanner;public class Hello {public static void main(String[] args) {Scanner in new Scanner(System.in);int number in.nextInt();int count 0;while( number > 0 ){number number / 10;count count 1;}System.out.println(count);} }...

G1JVM内存分配机制详解

为什么堆内存不是预期的3G&#xff1f; 当您设置-XX:MaxRAMPercentage75时&#xff0c;JVM并不会简单地将容器内存(4G)的75%全部分配给堆&#xff0c;原因如下&#xff1a; 计算基准差异&#xff1a; 百分比是应用于"可用物理内存"而非"容器总内存" &q…...

“端 - 边 - 云”三级智能协同平台的理论建构与技术实现

摘要 随着低空经济与智能制造的深度融合&#xff0c;传统集中式云计算架构在实时性、隐私保护和资源效率上的瓶颈日益凸显。本文提出“端 - 边 - 云”三级智能协同平台架构&#xff0c;以“时空 - 资源 - 服务”三维协同理论为核心&#xff0c;构建覆盖终端感知、边缘计算、云端…...

【UAP】《Empirical Upper Bound in Object Detection and More》

Borji A, Iranmanesh S M. Empirical upper bound in object detection and more[J]. arXiv preprint arXiv:1911.12451, 2019. arXiv-2019 文章目录 1、Background and Motivation2、Related Work3、Advantages / Contributions4、Experimental Setup4.1、Benchmarks Dataset…...

Web Service及其实现技术(SOAP、REST、XML-RPC)介绍

一.概述 1.Web Service&#xff08;Web 服务&#xff09; Web Service 由万维网联盟 (W3C) 定义为一种软件系统&#xff0c;旨在支持通过网络进行可互操作的计算机间交互。 广义概念&#xff1a;基于 Web 技术&#xff08;如 HTTP 协议&#xff09;的跨平台、跨语言通信机制…...

基于Spring Boot+Layui构建企业级电子招投标系统实战指南

一、引言&#xff1a;重塑招投标管理新范式 在数字经济浪潮下&#xff0c;传统招投标模式面临效率低、透明度不足、流程冗长等痛点。本文将以Spring Boot技术生态为核心&#xff0c;融合Mybatis持久层框架、Redis高性能缓存及Layui前端解决方案&#xff0c;构建一个覆盖招标代理…...

【嵌入式】记一次解决VScode+PlatformIO安装卡死的经历

PlatformIO 是开源的物联网开发生态系统。提供跨平台的代码构建器、集成开发环境&#xff08;IDE&#xff09;&#xff0c;兼容 Arduino&#xff0c;ESP8266和mbed等。 开源库地址&#xff1a;https://github.com/platformio 在 VScode 中配置 PlatformIO 插件&#xff0c;记录…...

抗量子计算攻击的数据安全体系构建:从理论突破到工程实践

在“端 - 边 - 云”三级智能协同理论中&#xff0c;端 - 边、边 - 云之间要进行数据传输&#xff0c;网络的安全尤为重要&#xff0c;为了实现系统总体的安全可控&#xff0c;将构建安全网络。 可先了解我的前文&#xff1a;“端 - 边 - 云”三级智能协同平台的理论建构与技术实…...

【FMMT】基于模糊多模态变压器模型的个性化情感分析

遇到很难的文献看不懂,不应该感到气馁,应该激动,因为外审估计也看不太懂,那么学明白了可以吓唬他 缺陷一:输入依赖性与上下文建模不足​​ ​​缺陷描述​​: 传统自注意力机制缺乏因果关系,难以捕捉序列历史背景多模态数据间的复杂依赖关系未被充分建模CNN/RNN类模型在…...

力扣Hot100(Java版本)

1. 哈希 1.1 两数之和 题目描述&#xff1a; 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案&#xff0c;并且你不能使用两次相同…...

Stream流简介、常用方法

Stream流的三类方法 获取Stream流 创建一条流水线&#xff0c;并把数据放到流水线上准备进行操作 中间方法 流水线上的操作一次操作完毕之后&#xff0c;还可以继续进行其他操作 终结方法 一个Stream流只能有一个终结方法是流水线上的最后一个操作 生成Stream流的方式 Collec…...

‌C# 集成 FastDFS 完整指南‌

‌1. 环境准备‌ ‌(1) 安装 FastDFS 服务端‌ 部署 Tracker 和 Storage 节点&#xff0c;确保服务正常运行。 配置 tracker_server 地址&#xff08;如 192.168.1.100:22122&#xff09;。 ‌(2) 添加 NuGet 包‌ 通过 NuGet 安装 FastDFS 客户端库&#xff1a; Install-Pack…...

重构门店网络:从“打补丁“到“造地基“的跨越

您是否遇到过这样的窘境&#xff1f; 新店开张要等一周&#xff0c;就为装根网线&#xff1b; 偏远地区门店三天两头断网&#xff0c;顾客排长队却结不了账&#xff1b; 总部想看实时数据&#xff0c;结果收到一堆乱码报错&#xff1b; 总部ERP系统升级&#xff0c;2000家门…...

TI的ADS1291代替芯片LH001-99

血管疾病严重威胁人类生命健康安全&#xff0c;随着人口老龄化进程的加快和社会压力等因素的增加&#xff0c;患病率正呈现逐年上升趋势&#xff0c;并且越来越年轻化。然而&#xff0c;心血管疾病大多由器官器质性病变引起&#xff0c;一旦患病很难完全康复&#xff0c;需要进…...

NPOI 操作 Word 文档

管理 NuGet 程序包 # word操作 NPOI# 图片操作 SkiaSharp Controller代码 using Microsoft.AspNetCore.Mvc; using NPOI.Util; using NPOI.XWPF.Model; using NPOI.XWPF.UserModel; using SkiaSharp;namespace WebApplication2.Controllers {[Route("api/Npoi/[action]…...

css3基于伸缩盒模型生成一个小案例

css3基于伸缩模型生成一个小案例 在前面学习了尚硅谷天禹老师的css3内容后&#xff0c;基于伸缩盒模型做的一个小案例&#xff0c;里面使用了 flex 布局&#xff0c;以及主轴切换&#xff0c;以及主轴平分等特性&#xff0c;分为使用css3 伸缩盒模型方式&#xff0c;已经传统的…...

精简大语言模型:用于定制语言模型的自适应知识蒸馏

Streamlining LLMs: Adaptive Knowledge Distillation for Tailored Language Models 发表&#xff1a;NAACL 2025 机构&#xff1a;德国人工智能研究中心 Abstract 诸如 GPT-4 和 LLaMA-3 等大型语言模型&#xff08;LLMs&#xff09;在多个行业展现出变革性的潜力&#xf…...

Rollup入门与进阶:为现代Web应用构建超小的打包文件

我们常常面临Webpack复杂配置或是Babel转译后的冗余代码&#xff0c;结果导致最终的包体积居高不下加载速度也变得异常缓慢&#xff0c;而在众多打包工具中Rollup作为一个轻量且高效的选择&#xff0c;正悄然改变着这一切&#xff0c;本文将带你深入了解这个令人惊艳的打包工具…...

博客系统技术需求文档(基于 Flask)

以下内容是AI基于要求生成的技术文档&#xff0c;仅供参考~ &#x1f9f1; 一、系统架构设计概览 层级 内容 前端层 HTML Jinja2 模板引擎&#xff0c;集成 Markdown 编辑器、代码高亮 后端层 Flask 框架&#xff0c;RESTful 风格&#xff0c;Jinja2 渲染 数据库 SQLi…...

快速排序、归并排序、计数排序

文章目录 前言一、归并排序算法逻辑递归实现非递归实现 二、快速排序算法介绍递归实现非递归实现算法的一种优化—三路划分法 四、计数排序算法原理代码实现优劣分析 五、排序算法的性能比较总结 前言 本文介绍这三种非常强大的排序算法&#xff0c;每种算法都有各自的特点、不…...

python语言与地理处理note 2025/05/11

1. 函数定义必须要在调用之前 &#xff08;1&#xff09;正确示例&#xff1a; def test():print("what a wonderful world!")test() &#xff08;2&#xff09;错误示例&#xff1a; test() def test():print("what a wonderful world!") 会报错&…...

贪心算法:最小生成树

假设无向图为&#xff1a; A-B:1 A-C:3 B-C:1 B-D:4 C-D:1 C-E:5 D-E:6 一、使用Prim算法&#xff1a; public class Prim {//声明了两个静态常量&#xff0c;用于辅助 Prim 算法的实现private static final int V 5;//点数private static final int INF Integer.MA…...

免费 OCR 识别 + 批量处理!PDF 工具 提升办公效率

各位办公小能手们&#xff01;今天给你们介绍一款超厉害的软件——PDF工具V2.2&#xff01;我跟你们说&#xff0c;这玩意儿就像是PDF界的超级英雄&#xff0c;专门搞定PDF文件的编辑、转换、压缩这些事儿。 先说说它的核心功能哈。基础文档管理方面&#xff0c;它能把好几个PD…...