LeetCode 248. Strobogrammatic Number III
来源:互联网 发布:ui设计需要会编程吗 编辑:程序博客网 时间:2024/05/22 17:46
原题网址:https://leetcode.com/problems/strobogrammatic-number-iii/
A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at upside down).
Write a function to count the total strobogrammatic numbers that exist in the range of low <= num <= high.
For example,
Given low = "50", high = "100", return 3. Because 69, 88, and 96 are three strobogrammatic numbers.
Note:
Because the range might be a large number, the low and high numbers are represented as string.
这是一个典型的深度优先搜索题目,我想在字符数值比较等地方提升搜索效率,于是写得比较恶心。
public class Solution { private char[] pair = {'0','1','6','8','9'}; private char[] rotated = {'0', '1', ' ', ' ', ' ', ' ', '9', ' ', '8', '6'}; private char[] self = {'0','1','8'}; private int find(char[] low, char[] high, boolean min, boolean max, char[] buf, int step) { if (step == buf.length) return 1; int count = 0; if ((step<<1) == buf.length) { // 当位数为偶数,且深度优先过半时 for(int i=step, j=step-1; i<buf.length; i++, j--) { buf[i] = rotated[buf[j]-'0']; if (min && buf[i] < low[i]) return 0; if (max && buf[i] > high[i]) return 0; if (buf[i] > low[i]) min = false; if (buf[i] < high[i]) max = false; } // System.out.printf("found %s\n", new String(buf)); return 1; } else if ((step<<1) == buf.length-1) { // 当位数为奇数,且深度优先处于中间数位时 for(int i=0; i<self.length; i++) { boolean nmin = min; boolean nmax = max; buf[step] = self[i]; if (min && buf[step] < low[step]) continue; if (max && buf[step] > high[step]) continue; if (buf[step] > low[step]) nmin = false; if (buf[step] < high[step]) nmax = false; count += find(low, high, nmin, nmax, buf, step+1); } } else if ((step<<1) > buf.length) { // 当位数为奇数,且深度优先过半时 for(int i=step, j=step-2; i<buf.length; i++, j--) { buf[i] = rotated[buf[j]-'0']; if (min && buf[i] < low[i]) return 0; if (max && buf[i] > high[i]) return 0; if (buf[i] > low[i]) min = false; if (buf[i] < high[i]) max = false; } // System.out.printf("found %s\n", new String(buf)); return 1; } else { // 深度优先未过半时 for(int i=0; i<pair.length; i++) { boolean nmin = min; boolean nmax = max; if (min && pair[i] < low[step]) continue; if (max && pair[i] > high[step]) continue; if (pair[i] > low[step]) nmin = false; if (pair[i] < high[step]) nmax = false; buf[step] = pair[i]; count += find(low, high, nmin, nmax, buf, step+1); } } return count; } public int strobogrammaticInRange(String low, String high) { if (low.length() > high.length()) return 0; char[] ha = high.toCharArray(); char[] la = low.toCharArray(); int lw = la.length; int count = 0; do { lw = la.length; char[] upper = ha; if (la.length < upper.length) { upper = new char[la.length]; Arrays.fill(upper, '9'); } // System.out.printf("low=%s, high=%s\n", new String(la), new String(upper)); count += find(la, upper, true, true, new char[la.length], 0); if (lw < ha.length) { la = new char[lw+1]; Arrays.fill(la, '0'); la[0] = '1'; } } while (lw < ha.length); return count; }}
方法二:当涉及到区间[A,B]的计算时,有个重要的思路是将区间转换为[0,B]-[0,A)
另外,深度优先不一定只是深度加1,可以是从两边向中间搜索。
public class Solution { private char[][] strobos = {{'0','0'}, {'1','1'}, {'6','9'}, {'8','8'}, {'9','6'}}; public int strobogrammaticInRange(String low, String high) { if (low.length() > high.length()) return 0; if (low.length() == high.length() && low.compareTo(high) > 0) return 0; return count(high, true) - count(low, false); } private int count(String high, boolean inclusive) { int len = high.length(); int count = 0; for(int i=1; i<len; i++) { count += countLen(i, true); } count += find(new char[len], 0, len-1, high.toCharArray(), inclusive, true); return count; } private int countLen(int len, boolean outside) { if (len == 0) return 1; if (len == 1) return 3; if (outside) return countLen(len-2, false)*4; return countLen(len-2, false)*5; } private int find(char[] num, int left, int right, char[] high, boolean inclusive, boolean ceiling) { if (left > right) { if (!ceiling) return 1; int compare = compare(num, high, left, num.length-1); if (inclusive && compare <= 0) return 1; if (!inclusive && compare < 0) return 1; return 0; } int count = 0; for(int i=0; i<strobos.length; i++) { if (left == 0 && right != 0 && strobos[i][0] == '0') continue; if (left == right && strobos[i][0] != strobos[i][1]) continue; if (ceiling && strobos[i][0] > high[left]) continue; num[left] = strobos[i][0]; num[right] = strobos[i][1]; count += find(num, left + 1, right - 1, high, inclusive, ceiling && num[left] == high[left]); } return count; } private int compare(char[] a, char[] b, int from, int to) { for(int i=from; i<=to; i++) { if (a[i] < b[i]) return -1; if (a[i] > b[i]) return 1; } return 0; }}
参考文章:
https://leetcode.com/discuss/73721/easiest-20ms-94%25-java-solution
https://leetcode.com/discuss/91136/java-0ms-solution-99-5%25
- LeetCode 248. Strobogrammatic Number III
- leetcode Strobogrammatic Number III
- [leetcode] 248. Strobogrammatic Number III 解题报告
- [Leetcode] 248. Strobogrammatic Number III 解题报告
- LeetCode 题解(240) : Strobogrammatic Number III
- [LeetCode248]Strobogrammatic Number III
- Leetcode: Strobogrammatic Number
- *LeetCode-Strobogrammatic Number
- [leetcode 246] Strobogrammatic Number
- Leetcode-246.Strobogrammatic Number
- LeetCode 246. Strobogrammatic Number
- LeetCode 246. Strobogrammatic Number
- Leetcode 246. Strobogrammatic Number
- Strobogrammatic Number -- Leetcode 246
- LeetCode 题解(238) : Strobogrammatic Number
- Leetcode NO.246 Strobogrammatic Number
- LeetCode 247. Strobogrammatic Number II
- LeetCode 247. Strobogrammatic Number II
- 用Artifactory管理内部Maven仓库
- 安卓助手应用商店全部源码
- Android 图片选取压缩上传功能需要注意的
- 读书笔记——雪花(1)Python基础
- 第四周项目2太乐了
- LeetCode 248. Strobogrammatic Number III
- 第五周项目二 游戏中的角色类
- 第五周项目3-时间类(2)
- 三角类锥形
- VMware workstation 11安装RHEL 6详细教程
- 设置IIS6.0的上传文件和下载附件的大小限制(验证过确实有效)
- 第五周项目三 时间类
- 草根创业秘诀:如何在3月内单月出货10万元
- 第5周项目2-游戏中的角色类(2)