LeetCode笔记:双指针技巧汇总
发布日期:2021-04-30 21:05:01
浏览次数:105
分类:精选文章
本文共 3779 字,大约阅读时间需要 12 分钟。
双指针技巧在算法中具有广泛的应用,尤其在链表和数组处理中表现突出。以下是双指针技巧的详细汇总,分为快慢指针和左右指针两大类,并包含多个实际应用示例。
一、快慢指针的常见算法
快慢指针通常用于链表问题,以下是典型应用:
判定链表中是否含有环
- 思路:使用两个指针,快指针每次前进两步,慢指针每次前进一步。当快指针和慢指针相遇时,若相遇位置在链表内部,则链表含有环。
- 实现:
public boolean hasCycle(ListNode head) { ListNode fast, slow; fast = slow = head; while (fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; if (fast == slow) { return true; } } return false;}
已知链表含有环,返回环的起始位置
- 思路:当快慢指针相遇时,重新让其中一个指针回到头节点,保持两个指针以相同速度前进,相遇点即为环起始位置。
- 实现:
public ListNode detectCycle(ListNode head) { ListNode fast, slow; fast = slow = head; while (fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; } slow = head; while (slow != fast) { fast = fast.next; slow = slow.next; } return slow;}
寻找链表的中点
- 思路:让快指针每次前进两步,慢指针每次前进一步。当快指针到达链表末尾时,慢指针即为中点。
- 实现:
public ListNode findMiddle(ListNode head) { ListNode slow, fast; slow = fast = head; while (fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; } return slow;}
寻找链表的倒数第k个元素
- 思路:让快指针先行k步,然后让两个指针以相同速度前进,当快指针到达末尾时,慢指针的位置即为目标元素。
- 实现:
public ListNode kthNode(ListNode head, int k) { ListNode slow, fast; slow = fast = head; while (k-- > 0 && fast != null) { fast = fast.next; } while (fast != null) { slow = slow.next; fast = fast.next; } return slow;}
二、左右指针的常用算法
左右指针通常用于数组或字符串问题,以下是典型应用:
二分查找
- 思路:初始化左右指针,分别表示数组的起始和结束位置,通过中间值比较目标值的位置,逐步缩小搜索范围。
- 实现:
public int searchInsert(int[] nums, int target) { int n = nums.length; int left = 0; int right = n - 1; while (left <= right) { int middle = left + ((right - left) / 2); if (nums[middle] > target) { right = middle - 1; } else if (nums[middle] < target) { left = middle + 1; } else { return middle; } } return -1;}
两数之和
- 思路:使用左右指针调整和,找到满足条件的数对。
- 实现:
public int[] twoSum(int[] nums, int target) { int left = 0, right = nums.length - 1; while (left < right) { int currentSum = nums[left] + nums[right]; if (currentSum == target) { return new int[]{nums[left], nums[right]}; } else if (currentSum < target) { left++; } else { right--; } } return new int[0];}
反转数组
- 思路:使用左右指针交换元素,直到左右指针相遇。
- 实现:
void reverseArray(int[] nums) { int left = 0, right = nums.length - 1; while (left < right) { int temp = nums[left]; nums[left] = nums[right]; nums[right] = temp; left++; right--; }}
滑动窗口算法
- 思路:维护一个窗口,记录字符频率,调整窗口大小以满足条件。
- 实现:
void slidingWindow(String s, String t) { Mapneed = new HashMap<>(); Map window = new HashMap<>(); for (char ch : t.toCharArray()) { need.put(ch, need.getOrDefault(ch, 0) + 1); } int left = 0, right = 0; int valid = 0; while (right < s.length()) { char c = s.charAt(right); if (c != t.charAt(right)) { right++; continue; } right++; while (valid < t.length() && window.size() > need.size()) { char d = s.charAt(left); if (d == t.charAt(left)) { valid--; } window.put(d, window.getOrDefault(d, 0) - 1); if (window.get(d, 0) == 0) { window.remove(d); } left++; } if (valid == t.length()) { return true; } } return false;}
总结
双指针技巧在链表和数组处理中发挥着重要作用,能够有效提高算法的效率。掌握这些技巧对解决LeetCode等算法题具有实战价值。通过不断练习和理解这些算法的原理,可以更深入地掌握相关知识,为后续的算法设计和优化打下坚实的基础。
发表评论
最新留言
路过,博主的博客真漂亮。。
[***.116.15.85]2026年06月07日 10时50分57秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
PHP7实战开发简单CMS内容管理系统(7) 后台登录架构 用户登录校验
2023-02-28
php7,从phpExcel升级到PhpSpreadsheet
2023-02-28
PHP8中match新语句的操作方法
2023-02-28
PHP:第一章——PHP中常量和预定义常量
2023-02-28
PHP:第一章——PHP中的位运算
2023-02-28
phpcms
2023-02-28
phpcms 2008 product.php pagesize参数代码注射漏洞
2023-02-28
phpcms V9 自定义添加 全局变量{DIY_PATH}方法
2023-02-28
Redis五种核心数据结构的基本使用与应用场景
2023-02-28
PHPCMS多文件上传和上传数量限制
2023-02-28
phpEnv的PHP集成环境
2023-02-28
PHPExcel一些基本设置总结
2023-02-28
PHPExcel导入导出 若在thinkPHP3.2中使用(无论实例还是静态调用(如new classname或classname::function)都必须加反斜杠,因3.2就命名空间,如/c...
2023-02-28
PHPMailer发送邮件
2023-02-28
phpmailer发送邮件,可以带附件
2023-02-28
phpmyadmin 安装
2023-02-28
phpmyadmin数据库建表及插入
2023-02-28
phprpc简单使用
2023-02-28
phpstorm中Xdebug的使用
2023-02-28
phpstorm中使用svn版本控制器
2023-02-28