双指针

双指针主要用来遍历数组,两个指针指向不同的元素,从而协同完成任务。


目录

  1. 有序数组的 Two Sum
  2. 两数平方和
  3. 反转字符串中的元音字符
  4. 回文字符串
  5. 归并两个有序数组
  6. 判断链表是否存在环
  7. 最长子序列

1. 有序数组的 Two Sum


题目描述:在有序数组中找出两个数,使它们的和为 target。

使用双指针,一个指针指向值较小的元素,一个指针指向值较大的元素。指向较小元素的指针从头向尾遍历,指向较大元素的指针从尾向头遍历。

  • 如果两个指针指向元素的和 sum == target,那么得到要求的结果;
  • 如果 sum > target,移动较大的元素,使 sum 变小一些;
  • 如果 sum < target,移动较小的元素,使 sum 变大一些;
  1. java版
public int[] twoSum(int[] numbers, int target) {int i = 0, j = numbers.length - 1;while (i < j) {int sum = numbers[i] + numbers[j];if (sum == target)return new int[]{i + 1, j + 1};else if (sum > target)j--;elsei++;}return null;}
  1. go版
func twoSum(nums []int, target int) []int {m := make(map[int]int)for i, num := range nums {diff := target - numif _, ok := m[diff]; ok {return []int{m[diff], i}}m[num] = i}return nil
}

2. 两数平方和


题目描述:判断一个数是否为两个数的平方和。

  1. java
public boolean judgeSquareSum(int C) {int i = 0, j = (int) Math.sqrt(C);while (i <= j) {int sum = i * i + j * j;if (sum == C)return true;else if (sum < C)i++;elsej--;}return false;}
  1. go版
func judgeSquareSum(c int) bool {i, j := 0, int(math.Sqrt(float64(c)))for i <= j {target := i*i + j*jif target == c {return true} else if target < c {i++} else if target > c {j--}}return false
}

3. 反转字符串中的元音字符


使用双指针指向待反转的两个元音字符,一个指针从头向尾遍历,一个指针从尾到头遍历。

  1. java
private final static HashSet<Character> vowels =new HashSet<>(Arrays.asList('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'));public String reverseVowels(String s) {int i = 0, j = s.length() - 1;char[] result = new char[s.length()];while (i <= j) {char ci = s.charAt(i);char cj = s.charAt(j);if (!vowels.contains(ci)) {result[i++] = ci;} else if (!vowels.contains(cj)) {result[j--] = cj;} else {result[i++] = cj;result[j--] = ci;}}return new String(result);}
  1. go
func reverseVowels(s string) string {b := []byte(s)for i, j := 0, len(b)-1; i < j; {if isVowels(b[i]) && isVowels(b[j]) {b[i], b[j] = b[j], b[i]i++j--} else if !isVowels(b[i]) && isVowels(b[j]) {i++} else if isVowels(b[i]) && !isVowels(b[j]) {j--} else {i++j--}}return string(b)
}func isVowels(s byte) bool {if s == 'a' || s == 'e' || s == 'i' || s == 'o' || s == 'u' || s == 'A' || s == 'E' || s == 'I' || s == 'O' || s == 'U' {return true}return false
}

4. 回文字符串


题目描述:删除一个字符,判断是否能构成回文字符串。

  1. java
public boolean volidPalindrome(String s) {for (int i = 0, j = s.length() - 1; i < j; i++, j--) {if (s.charAt(i) != s.charAt(j)) {return isPalindrome(s, i + 1, j) || isPalindrome(s, i, j - 1);}}return true;}private boolean isPalindrome(String s, int i, int j) {while (i < j) {if (s.charAt(i++) != s.charAt(j--)) {return false;}}return true;}
  1. go
func validPalindrome(s string) bool {b := []byte(s)for i, j := 0, len(b)-1; i <= j; {if b[i] == b[j] {i++j--} else if b[i] != b[j] {return isPal(b, i+1, j) || isPal(b, i, j-1)}}return true
}func isPal(b []byte, i int, j int) bool {for i<=j{if b[i]==b[j]{i++j--}else {return false}}return true
}

5. 归并两个有序数组


题目描述:把归并结果存放到第一个数组上。

思路:需要从尾到头遍历,否则在 num1 上归并得到的值会覆盖还未进行归并比较的值。

  1. java
public void merge(int[] num1, int m, int[] num2, int n) {int index1 = m - 1, index2 = n - 1;int indexMerge = m + n - 1;while (index1 >= 0 || index2 >= 0) {if (index1 < 0) {num1[indexMerge--] = num2[index2--];} else if (index2 < 0) {num1[indexMerge--] = num1[index1--];} else if (num1[index1] > num2[index2]) {num1[indexMerge--] = num1[index1--];} else {num1[indexMerge--] = num2[index2--];}}}
  1. go
func merge(nums1 []int, m int, nums2 []int, n int) {for i, j, tail := m-1, n-1, m+n-1; i >= 0 || j >= 0; tail-- {var cur intif i == -1 {cur = nums2[j]j--} else if j == -1 {cur = nums1[i]i--} else if nums1[i] > nums2[j] {cur = nums1[i]i--} else {cur = nums2[j]j--}nums1[tail] = cur}
}

6. 判断链表是否存在环


思路:使用双指针,一个指针每次移动一个节点,一个节点每次移动两个节点,如果存在环,那么这两个指针一定会相遇。

  1. java
public boolean hasCycle(ListNode head) {if (head == null)return false;ListNode l1 = head;ListNode l2 = head;while (l1 != null && l2 != null && l2.next != null) {if (l1 == l2)return true;l1 = l1.next;l2 = l2.next.next;}return false;}
  1. go
func hasCycle(head *ListNode) bool {fast ,slow := head,headfor slow!=nil &&fast!=nil && fast.Next!=nil{fast = fast.Next.Nextslow = slow.Nextif fast==slow{return true}}return false
}

7. 最长子序列


题目描述:删除 s 中的一些字符,使得它构成字符串列表 d 中的一个字符串,找到能构成的最长字符串。如果有多个相同长度的结果,返回字典的最小字符串。

思路:通过删除字符串 s 中的一个字符能得到字符串 t,可以认为 t 是 s 的子序列,我们可以使用双指针来判断一个字符串是否为另一个字符串的子序列。

  1. java
public String findLongestWord(String s, List<String> d) {String longestWord = "";for (String target : d) {int l1 = longestWord.length(), l2 = target.length();if (l1 > l2 || (l1 == l2 && longestWord.compareTo(target) < 0)) {continue;}if (isSubstr(s, target)) {longestWord = target;}}return longestWord;}private boolean isSubstr(String s, String target) {int i = 0, j = 0;while (i < s.length() && j < target.length()) {if (s.charAt(i) == target.charAt(j)) {j++;}i++;}return j == target.length();}
  1. go
func findLongestWord(s string, d []string) string {longestWord := ""          // 记录当前最长字符串for _, target := range d { // 获取每一个目标字符串i, j := len(longestWord), len(target)if i > j || (i == j && strings.Compare(longestWord, target) < 0) { //如果当前最长字符串大于目标字符串或者两者长度相等,但内容不一样,continuecontinue}if isSubstr(s, target) { //判断是否是子串,如果是,更新reslongestWord = target}}return longestWord
}func isSubstr(s, target string) bool {i, j := 0, 0for i < len(s) && j < len(target) { // 遍历,但不能超过最长长度if s[i] == target[j] { //如果两者字符相等,j++j++}i++ // 往下遍历}return j == len(target)
}

LeetCode——双指针相关推荐

  1. Leetcode—双指针

    双指针篇 简单 验证回文串 leetcode直达 class Solution {public:bool isPalindrome(string s) {int left = 0;int right ...

  2. Leetcode双指针滑动窗口相关题目

    滑动窗口 滑动窗口解决哪种问题? 滑动窗口解决给定两个字符串S和T,问你S中是否存在一个子串,包含T中的所有字符并且不含有其他字符. 窗口右指针向右移动,窗口增大,直到满足条件,这时候找到可行解. 窗 ...

  3. leetcode双指针合集

    27. 移除元素 class Solution {public:int removeElement(vector<int>& nums, int val) {/**思路:使用快慢指 ...

  4. leetcode双指针(python与c++)

    1.字符串的排列 思路:双指针+滑动窗口 python: class Solution:def checkInclusion(self, s1: str, s2: str) -> bool:di ...

  5. leetcode ---双指针+滑动窗体

    一:Minimum Size Subarray Sum(最小长度子数组的和O(N)) 题目: Given an array of n positive integers and a positive ...

  6. leetcode+双指针求最大容积,思维。一左一右指针

    点击打开链接 #include<iostream> #include<stdio.h> #include<stdlib.h> #include<string& ...

  7. 备战秋招 |《百面机器学习》算法+leetcode开班报名!

    算法面试刷题班推荐: 以<百面机器学习>为教材 结合leetcode筛选刷题 秋招已经开始了!时间紧迫,也许别人已经得到offer了,你却还在不知所措?(文末重金招聘讲师) 六月份基本都是 ...

  8. 仅剩3天 | 带学《百面机器学习》葫芦书,算法+leetcode一应俱全

    或许你只要比别人准备多一点,你就可以在群体中脱颖而出. 年后基本都是春招和社招的高峰期,但好岗位招聘人数和应聘人数简直堪比春运抢票. 你总在抱怨"为什么别人机会那么好,能抢到你想要的名额?& ...

  9. 【只推荐一位】文能写诗聊妹,武可搬砖coding~

    今天给大家推荐一个双一流高校在读研究生--小詹,「一个文能写诗撩妹,武可搬砖coding」的程序猿- 可上九天揽月,可下五洋捉鳖!说点题外话,不知道各位看到这句话第一反应是什么? 估计不少人认为是可以 ...

最新文章

  1. Apache shiro
  2. 双协议栈服务器,10. 搭建双协议栈Web服务器:使用IPv6地址、IPv4
  3. jQuery 树形控件 TreeView 的 Bug
  4. 爬虫套路知多少?反爬策略是关键
  5. 计算机图形学の三种经典画直线算法
  6. java 二进制文件修改_Java读写二进制文件操作
  7. Cohen's d 效应量计算
  8. 三极管电路限流电阻如何选择
  9. layabox 位移动画旋转动画
  10. keepalived实现服务高可用
  11. matlab hold all,Matlab中的命令hold on hold off | 学步园
  12. Visual C++开发类似QQ游戏大厅全过程
  13. 用好工具,在团队协作中运筹帷幄
  14. 应用排行榜第一名脸萌仅仅是刹那的烟火
  15. 计算机装系统找不到硬盘,电脑重装系统找不到硬盘驱动器怎么办?
  16. app抓包于appium爬取数据
  17. 【Vue实用功能】Vue实现浏览器全屏退出全屏
  18. 签名服务器支付系统,基于短签名的电子银行支付认证系统设计与实现
  19. 工银亚洲见证开户详细过程和攻略
  20. 解决报错dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.64.dylib

热门文章

  1. 微软System Center Operations Manager 2012(SCOM )安装图文教程
  2. 控制台 - 网络管理之华为交换机 S系列端口限速
  3. SQL 备份还原单个表
  4. sql 统计用的sql
  5. linux-dns的安装
  6. JavaScript栈的实现
  7. 取石子游戏与SG函数
  8. Duilib教程-非DUI控件
  9. 关于网狐棋牌6603源码的整理、编译和搭建
  10. 如何打造不怕被嗅探的3389登陆