前言
今天的题目按照顺序的话应该是第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:
输入:[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题可以看出,双指针在解题中很常见,也很有用,通过几道题明显的感觉到比暴力破解快很多,类似的还有前文描述的三数之和等都是使用了双指针。
双指针,或者跟多的三指针问题都是有着一定的规律,这些题都有着不断压缩搜索距离的特征,以后再遇到类似的题目可以轻车熟路。
今天多学一点,明天就少说一句求人的话,加油!