【算法攻坚】双指针技巧解题

简介: 【算法攻坚】双指针技巧解题

前言


今天的题目按照顺序的话应该是第8题字符串转换整数 (atoi),但是这道题完全是对字符串的边界转换考察,个人认为并没有什么算法思想,所以这次跳过第8题。


今日题目1


给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。


示例 1:


输入:x = 121 输出:true


示例 2:


输入:x = -121 输出:false 解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。


示例 3:


输入:x = 10 输出:false 解释:从右向左读, 为 01 。因此它不是一个回文数。


示例 4:


输入:x = -101 输出:false

进阶:你能不将整数转为字符串来解决这个问题吗?


思路


前面刷到的第5题,最长回文子串中已经介绍了回文的意思

这里回文数,其实也是类似,回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数


这道题思路也是通过双指针方式,来判断前后是否相同

如果数字为负数,直接返回false,因为有‘-’所以一定不是回文数


public boolean isPalindrome(int x) {
    if( x < 0){
        return false;
    }
    String s = String.valueOf(x);
    int left = 0, right = s.length()-1;
    while(left <= right){
        if(s.charAt(left) == s.charAt(right)){
            left++;
            right--;
        }else{
            return false;
        }
    }
    return true;
}


执行用时:6 ms, 在所有 Java 提交中击败了96.93%的用户

内存消耗:37.9 MB, 在所有 Java 提交中击败了46.32%的用户


解法二


再次看下回文数的定义 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数

也就说把数字翻转后与翻转前数值相当,这时就可以利用前文的整数翻转思路

public boolean isPalindrome(int x) {
    if( x < 0){
        return false;
    }
    int temp = x;
    long result = 0;
    while(x != 0){
        int cuur = x %10;
        result = result * 10 + cuur;
        x = x /10;
    }
    return temp == result;
}


执行用时:5 ms, 在所有 Java 提交中击败了98.60%的用户

内存消耗:37.8 MB, 在所有 Java 提交中击败了54.14%的用户


今日题目2


给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。


说明:你不能倾斜容器。


示例 1:


image.png


输入:[1,8,6,2,5,4,8,3,7] 输出:49 解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。


示例 2:


输入:height = [1,1] 输出:1


示例 3:


输入:height = [4,3,2,1,4] 输出:16


示例 4:


输入:height = [1,2,1] 输出:2

提示:

n == height.length 2 <= n <= 105 0 <= height[i] <= 104


思路


本题解法也是双指针,一开始两个指针一个指向开头一个指向结尾,此时容器的底是最大的,

接下来随着指针向内移动,会造成容器的底变小,在这种情况下想要让容器盛水变多,就只有在容器的高上下功夫。


那该如何决策哪个指针移动呢?我们能够发现不管是左指针向右移动一位,还是右指针向左移动一位,容器的底都是一样的,都比原来减少了 1。


这种情况下我们想要让指针移动后的容器面积增大,就要使移动后的容器的高尽量大,所以我们选择指针所指的高较小的那个指针进行移动,这样我们就保留了容器较高的那条边,放弃了较小的那条边,以获得有更高的边的机会。


把每次移动后的体积最大值保存,然后移动指针,为什么移动小的指针就可以呢?

这是因为高度由两边中矮的一边决定,


所以如果移动高的一边,即使遇到再高的,体积也不会变大

如果移动短的就可能变大,也可能变小


实现


public int maxArea(int[] height) {
    int result = 0;
    int left = 0, right = height.length -1;
    while(left < right){
        //两边哪个短,移动哪个指针
        if(height[left] < height[right]){
            result = Math.max(result, height[left]*(right - left));
            left++;
        }else{
            result = Math.max(result, height[right]*(right - left));
            right--;
        }
    }
    return result;
}


执行用时:3 ms, 在所有 Java 提交中击败了92.67%的用户

内存消耗:51.8 MB, 在所有 Java 提交中击败了64.99%的用户


小结


从力扣第9/10题可以看出,双指针在解题中很常见,也很有用,通过几道题明显的感觉到比暴力破解快很多,类似的还有前文描述的三数之和等都是使用了双指针。

双指针,或者跟多的三指针问题都是有着一定的规律,这些题都有着不断压缩搜索距离的特征,以后再遇到类似的题目可以轻车熟路。

今天多学一点,明天就少说一句求人的话,加油!


目录
相关文章
|
5月前
|
算法
双指针算法
双指针算法
32 2
|
2月前
|
算法 索引 容器
双指针算法详解
本文介绍了双指针算法及其应用。双指针算法是在数组或字符串中常用的高效技术,通过维护两个指针遍历数据结构以解决特定问题。根据指针移动方向,可分为同向双指针、相向双指针和快慢指针。同向双指针如移动零和复写零问题;快慢指针如快乐数问题;相向双指针如盛水最多的容器、有效三角形数量及多数之和等问题。通过合理运用双指针技巧,可简化代码并提高效率。
63 4
双指针算法详解
|
1月前
|
算法 Java 程序员
【算法每日一练及解题思路】有n级台阶,一次只能上1级或2级,共有多少种走法?
本文深入解析了“爬楼梯问题”,探讨了递归与迭代两种解法,并提供了Java代码实现。通过分析问题本质,帮助读者理解动态规划技巧,提高解决实际编程问题的能力。关键词:Java, 算法, 动态规划, 爬楼梯问题, 递归, 迭代。
72 0
|
1月前
|
算法 C++
【算法解题思想】动态规划+深度优先搜索(C/C++)
【算法解题思想】动态规划+深度优先搜索(C/C++)
|
1月前
|
算法 C++
【算法】双指针+二分(C/C++
【算法】双指针+二分(C/C++
|
3月前
|
算法 容器
【算法】双指针
【算法】双指针
|
3月前
|
算法 C++ 容器
【C++算法】双指针
【C++算法】双指针
|
5月前
|
算法 C语言
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
42 2
|
5月前
|
算法
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表

热门文章

最新文章

下一篇
无影云桌面