近期刷题小结:
之前的方法主要是转成字符串,或者是翻转数字之后比较。但是题目要求不能使用额外的空间,所以需要直接取出数字的首末位比较。先求得数字的位数,然后用(x % 10) != (x / (int) (Math.pow(10, len – 1))) 比较头尾,每次比较完之后会掐头去尾得到一个新的数,依次可求是否为回文数。
模式匹配还是需要用到递归的,看起来也比较清楚。每次获取两个字符串的首位,然后主要有两种情况:1、单个字符,且后续没有*号,直接比较,然后比较各自-1的子串;2、后续有*号,这种情况相对复杂,又分成三种可能,最常见的是aaa和a*这样,a*匹配所有的a;一种是像aaa和aa*a这种,可能a*只匹配1个a;另外一种是像aa和c*a*,c*根本不匹配。
暴力算法就是循环两遍,找到所有的组合比较,效率较低
可以分析得出,如果从两端开始计算,依次缩小范围,只有可能中间的两块板特别高,才有可能比摊平的要大。所以依次取left和right计算area,然后将较小的抛弃,计算内部的可能area。
这两个的思想都是先定义了对应关系:
int[] nums = { 1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000 };
String[] romans = { “I”, “IV”, “V”, “IX”, “X”, “XL”, “L”, “XC”, “C”, “CD”, “D”, “CM”, “M” };
然后使用累加的思想,每次累加依次,就输出一个罗马数字,这也是罗马数字本身的思想。比如III是3个1累加和VI是5加1
反过来也是,依次从最大的开始匹配字符串,然后累加,比如DCXXI,依次匹配D,C,X,X,I,因为不存在DC或者XI这样的组合
注意都是要从最大的数开始累加
这个的思想比较直接,时间复杂度是O(nm),n个字符串,m是最长前缀子串的长度。
依次取出第i个字符,看是不是每个字符串都包括,如果包括就加入common prefix