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

[Java算法] 双指针(1)

1.移动零

解法1:

public class double_pointer_01 {public static void moveZeroes(int[] nums) {int dest = 0;int cur = 0;while(cur<nums.length&&dest<=cur){while(nums[cur]==0&&dest<=cur){cur++;// 防止cur越界(当数组全为0时,cur会超过数组长度)if (cur >= nums.length) {return;}}while(nums[dest]!=0 && dest<cur){dest++;if(dest>cur){return;}}swap(nums,dest,cur);dest++;cur++;}}public static void swap(int[] nums , int dest , int cur){int tmp = nums[dest];nums[dest] = nums[cur];nums[cur] = tmp;}public static void main(String[] args) {int[] nums = {0,1,0,3,12};moveZeroes(nums);for (int x:nums) {System.out.println(x);}}}

解法2 : 

public void moveZeroes2(int[] nums){for(int cur = 0,dest = -1;cur < nums.length;cur++){if(nums[cur]!=0) {dest++;swap(nums, dest, cur);}}
}
public static void swap(int[] nums , int dest , int cur){int tmp = nums[dest];nums[dest] = nums[cur];nums[cur] = tmp;
}

运用到快速排序的思想

2.复写零

class Solution {public void duplicateZeros(int[] arr) {int count = 0;int len = arr.length;int cur = 0;for(cur = 0;cur<=len-1;cur++){if(count>=len){break;}if(arr[cur] == 0){count+=2;}else{count++;}}int dest = len-1;cur--;if(count == len+1){arr[dest--] = 0;cur--;}while(cur>=0&&dest>=0){if(arr[cur]!=0){arr[dest--] = arr[cur--];}else{arr[dest--] = 0;arr[dest--] = 0;cur--;}}}
}

算法思路

用 count 来标记统计结束的下标 , cur 找结束的位置 , 如果 cur 是 0 则 cout+2 , 非零加一 ,

cur 回退 1????没懂 , 自己画图没有问题 , 代码跑起来有问题

再判断 count 的长度是否是比 len 多 1(末尾为 0),是则做处理

最后从后往前复写操作

3.快乐数

class Solution {public static boolean isHappy(int n) {if(n == 1||sum_squares(n) == 1){return true;}int slow = sum_squares(n);int fast = sum_squares(sum_squares(n));while(slow != fast){slow = sum_squares(slow);fast = sum_squares(sum_squares(fast));if(slow == 1||fast == 1){return true;}}return false;}public static int sum_squares(int n){int sum = 0;while(n!=0){int tmp = n % 10;sum = sum + tmp*tmp;n /= 10;}return sum;}
}
public class demo2 {public static void main(String[] args) {Solution s = new Solution();boolean a = s.isHappy(19);System.out.println(a);}
}

算法思路

  1. 先写出求各给数位上的平方之和 的方法
  2. 如果 n 为 1 或者各给数位的平方和为 1 (例如 10,100,1000 等)直接返回 true
  3. 让 slow 往后走一步(调用一次方法) , 让 fast 往后走两步(调用两次方法).(快慢指针法)
  4. 一直到他俩相遇 (此题他们必定会形成一个环(抽屉原理)) , 在循环的过程中如果 slow 或者 fast 的值为 1 , 那么结束循环 , 为快乐数;如果在循环过程中 , 知道 slow 和 fast 相遇都没有变为 1 , 那么不是快乐数

4.盛最多水的容器

public int maxArea(int[] height) {int left = 0;int right = height.length-1;int len = right-left;int h = (height[left]<height[right])?height[left]:height[right];int maxVolume = len*h;if(height[left]<height[right]){left++;}else{right--;}while(left!=right){len = right-left;h = (height[left]<height[right])?height[left]:height[right];int volume = len*h;maxVolume = (maxVolume>volume)?maxVolume:volume;if(height[left]<height[right]){left++;}else{right--;}}return maxVolume;}

算法思路:

    • 初始指针:左指针left在数组起始位置(0),右指针right在数组末尾(height.length-1),此时两指针距离最大。
    • 计算当前面积:以两指针距离为底,较短的垂线高度为高,乘积为当前面积。
    • 指针移动策略:移动较短垂线的指针(贪心选择)。因为若移动较长垂线,底边长减少,高度不会超过当前较短垂线,面积必然减小;而移动较短垂线可能遇到更高的垂线,从而获得更大面积。
    • 循环终止:左右指针相遇(left == right)时,所有可能的组合已遍历。

图解:

5.有效三角形的个数

class Solution {public int triangleNumber(int[] nums) {quickSort(nums ,0, nums.length - 1);int larger = nums.length-1;int count = 0;while(larger>=2){int left = 0;int right = larger-1;while(right>left){if(nums[left]+nums[right]>nums[larger]){count += right-left;right--;}else{left++;}}larger--;}return count;}public void quickSort(int[] arr, int low, int high) {if (low < high) {int pivotIndex = partition(arr, low, high); // 分区,返回基准值的最终位置quickSort(arr, low, pivotIndex - 1); // 递归排序左半部分quickSort(arr, pivotIndex + 1, high); // 递归排序右半部分}}public int partition(int[] arr, int low, int high) {int pivot = arr[high]; // 选最后一个元素作为基准值int i = low - 1; // i记录“小于基准值”区域的右边界for (int j = low; j < high; j++) {if (arr[j] < pivot) {i++;// 交换arr[i]和arr[j],将小于基准的元素移到左半区int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}// 将基准值放到最终位置(i+1的位置)int temp = arr[i + 1];arr[i + 1] = arr[high];arr[high] = temp;return i + 1;}
}

补充 : 当三个数为有序时 , 只需判断两个较小数之和是否大于较大数即可 , 如果两个较小数之和大于较大数则是三角形 , 无需再判断剩下两类

算法步骤:

    • 排序:先对数组排序(升序),方便固定最长边并利用双指针寻找有效组合。
    • 固定最长边:从数组末尾开始,依次将 nums[larger] 作为最长边(largern-1 递减到 2,因至少需要 3 条边)。
    • 双指针找有效组合:对每个最长边 nums[larger],用左指针 left=0、右指针 right=larger-1 寻找符合 nums[left] + nums[right] > nums[larger] 的组合:
      • 若满足条件:说明 leftright-1 之间的所有边与 nums[right] 搭配,均能与最长边构成三角形(因数组有序,nums[left] 最小),因此直接累加 right-left 到结果。
      • 若不满足条件:需右移 left 增大两边之和。
    • 循环直至所有最长边都被处理。

图解

http://www.dtcms.com/a/585739.html

相关文章:

  • 江苏省建设厅网站官网湖南做网站最厉害的公司
  • 杭州家具网站建设方案郑州app开发价格
  • gdb调试命令和GDB 到 LLDB 命令映射
  • 【CUDA笔记】02 CUDA GPU 架构与一般的程序优化思路(上)
  • 198种组合算法+优化XGBoost+SHAP分析+新数据预测!机器学习可解释分析,强烈安利,粉丝必备!
  • 东莞做网站要多少钱安顺建设局网站官网
  • 在线做h5 的网站网站服务器怎么查询
  • Vue 项目实战《尚医通》,展示已有医院的数据并分页展示,笔记11
  • Modbus RTU 转 Modbus TCP:借助数据采集提升三菱PLC冷库温度反馈实时性案例
  • DeepSeek-OCR实战(01):基础运行环境搭建-Ubuntu
  • SQLite 索引:优化数据库查询的关键
  • 可拖拽网站三星官网商城
  • MySQL 8.x 的 my.ini配置设置
  • 周志华《机器学习导论》第 15 章 规则学习(符号主义学习)
  • 使用pycharm自带debug模式运行flask时报错
  • 福州做网站需要多少钱懒设计app
  • Dify 安全架构设计
  • 网站推广国外网站建设素材库
  • Rust 练习册 :Pythagorean Triplet与数学算法
  • 构建一个短链接生成器服务(FastAPI + SQLite)
  • 基于SpringBoot智慧社区系统/乡村振兴系统/大数据与人工智能平台
  • 做网站的公司跑了wordpress 首页显示产品
  • BLDCPMSM电机控制器硬件设计工程(八)72V 10kW电机控制器原理图工程及库文件
  • 西宁的网站建设公司怎样建立网站的快捷方式
  • MATLAB基于IOWGA算子的最优组合预测模型及应用
  • HarmonyOS Web组件深度解析:构建高性能JavaScript交互的实践与创新
  • 华为OD机试双机位A卷 - 竖直四子棋 (JAVA Python C++ JS GO)
  • Qt C++:跨平台开发利器
  • 愿景 做中国最受欢迎的互联网网站阿里云建站论坛网站
  • HotpotQA:推动多跳推理问答发展的标杆数据集