2018-09-21

zigzag

https://leetcode-cn.com/problems/zigzag-conversion/
思路一:

WechatIMG58.jpeg

建一个二维数组,存zigzag图形(char初始值为0)
把字符换成下标来排列,更容易发现规律
找到循环一次需要的字符数 : int circle = 2*(numRows-1);
一个circle分成两部分:从上到下 和 斜着的从下到上

  • 从上到下的是竖直的:行等于它在circle中的位置,列是每个circle的第一列。每个circle占numRows-1列。所以列下标 = i/circle*(numRows-1)
  • 从下到上是斜的:这样的斜对角线一般满足 横坐标+纵坐标 = 每个常数
    而由于可能有多个circle,所以实际情况是 横坐标 + (纵坐标-之前的circle所占列数)= numRows-1。横坐标是倒着的,表示差多少到1个circle,横坐标 = circle-mod;纵坐标 = numRows-1-横坐标 + 之前的circle所占列数 = mod - (numRows-1) + i/circle*(numRows-1)
    易错点
    char初始值判断:0
    s为空和numRows=1的情况
class Solution {
    public String convert(String s, int numRows) {
        if(s==null||s.length()==0||numRows==1)return s;
        int n = s.length();
        int circle = 2*(numRows-1);
        int col = ((n-1)/circle+1)*(numRows-1);
        char[][] result = new char[numRows][col];
        for(int i=0;i<n;i++){
            int mod = i%circle;
            int devide = i/circle;
            if(mod<numRows-1){
                result[mod][devide*(numRows-1)] = s.charAt(i);
            }else{
                result[circle-mod][devide*(numRows-1)+(mod-(numRows-1))] = s.charAt(i);
            }
        }
        char[] resultArray = new char[n];
        int index = 0;
        for(int i=0;i<result.length;i++){
            for(int j=0;j<result[0].length;j++){
                if(result[i][j]!=0){
                    resultArray[index++] = result[i][j];
                }
            }
        }
        return new String(resultArray);
    }
}

思路2
不借助额外的空间要怎么做呢?
一定是需要寻找规律了。
如果有0-21个字符。
row 0: 0,circle,circle*2....
row i:0*circle+i,1*circle-i,1*circle+i,2*cirlce-i,...
row numRows-1: numRows-1,1*circle+numRows-1,2*circle+numRows-1

所以我们发现规律,除了第1行和最后一行,中间的i行都符合上述规律。而第1行和最后一行,特殊在只算了+i的,没有-i。
那么,我们可以顺序地填充结果数组。每次判断应有的下标是否超限,按照+i,(index++),-i的顺序依次循环,一旦发现当前下标不满足了,就跳到下一行,并且重新循环判断。
指的注意的是,在第一行和最后一行时,不执行-i的步骤。

class Solution {
    public String convert(String s, int numRows) {
        if(s==null||s.length()==0||numRows==1)return s;
        int n = s.length();
        char[] result = new char[n];
        int row = 0;
        int index = 0;
        int circle = 2*(numRows-1);
        for(int i=0;i<n;){
            if((index*circle+row)<n){
                result[i++] = s.charAt(index*circle+row);
            }else{
                row++;
                index =0;
                continue;
            }
            index++;
            if(row==0 || row==numRows-1){
                continue;
            }else if((index*circle-row)<n){
                result[i++] = s.charAt(index*circle-row);
            }else{
                row++;
                index =0;
                continue;
            }
        }
        return new String(result);
    }
}

516.Longest Palindromic Subsequence(最长回文子序列)

子序列有顺序,可以不连续
bbbab的最长回文子序列长度为4
思路:

  • 动态规划。n=s.length(),设立一个n行,n列的dp数组。
    d[i][j]代表s中下标i到j的子串中,最长回文子序列的长度。我们最后需要返回的是d[0][n-1]的值
  • 易得 d[i][i]=1边界条件。
  • dp数组这样更新,有两个指针i和j。指针i从尾部一直向前遍历到头,j从i的下一个元素一直遍历到尾部。
  • 如果i,j指向的字符相等,说明能够添加到i~j的回文串的长度中,即d[i][j]=d[i+1][j-1]+2;
  • 如果不相等,说明i ,j所指的两个元素对回文串长度无贡献,则dp[i][j]就是从dp[i+1][j]和dp[i][j-1]中选取较大的一个值即可

注意
1.状态转移方程要求d[i+1][j-1],dp[i+1][j],dp[i][j-1]都在d[i][j]之前就计算出来,也即开头更靠后的要先计算。所以i从末尾向前遍历。
2.d[i][i+1]的情况也符合递推式。因为d[i+1][i]的初始值为0

class Solution {
    public int longestPalindromeSubseq(String s) {
        if(s==null||s.length()==0)return 0;
        int n = s.length();
        int[][] d = new int[n][n];
        for(int i=n-1;i>=0;i--){
            d[i][i]=1;
            for(int j=i+1;j<n;j++){
                if(s.charAt(i)==s.charAt(j)){
                    d[i][j] = d[i+1][j-1] + 2;
                }else{
                    d[i][j] = Math.max(d[i+1][j],d[i][j-1]);
                }
            }
        }
        return d[0][n-1];
    }
}

最长回文子串

回文子串的判断,两个指针从两头到中间指向的字符都相等,就是回文字符串;或者反转字符串,和原字符串一样,也说明是回文字符串。
思路一:
动态规划。
//dp[i][i]=1
//如果s[i]==s[j]&&dp[i+1][j-1]==1则dp[i][j]=1;否则dp[i][j]=0
//dp[i][j]代表i~j的子串是不是回文字符串
//初始化:dp[i][<i]认为是空字符串,空的也算是回文。不然aa这里计算会出错

class Solution {
    public String longestPalindrome(String s) {
        if(s==null||s.length()==0)return s;
        int start=0;
        int end = 0;
        int n=s.length();
        int[][] dp = new int[n][n];
        int max = 0;
        //初始化:dp[i][<i]认为是空字符串,空的也算是回文。不然aa这里计算会出错
        for(int i=0;i<n;i++){
            for(int j=0;j<i;j++){
                dp[i][j]=1;
            }
        }
        //dp[i][i]=1
        //如果s[i]==s[j]&&dp[i+1][j-1]==1则dp[i][j]=1;否则dp[i][j]=0
        //dp[i][j]代表i~j的子串是不是回文字符串
        for(int i=n-1;i>=0;i--){
            dp[i][i]=1;
            for(int j=i+1;j<n;j++){
                if(s.charAt(i)==s.charAt(j)&&dp[i+1][j-1]==1){
                    dp[i][j]=1;
                    if(max<(j-i+1)){
                        max = j-i+1;
                        start =i;
                        end = j;
                    }
                }else{
                    dp[i][j]=0;
                }
            }
        }
        return s.substring(start,end+1);
    }
}

思路2
反转字符串(n),求和原字符串的公共子串,如果公共子串是回文字符串且最长,就是原字符串的最长回文子字符串。

思路3
从头到尾,每个当做是mid,向两头扩展,如果两头指针指向的字符不相等了,就停止。记录最长长度。
如果遇到 baab这种情况,把它当做bab来看,也即right++直到不和mid相等。是O(n^2)的解法。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容

  • 1、原则是建立在底线之上的做人处世的规则与规范及宽容度,原则是对与错,是与否的辩证,是水平方向的量。 2、底线,就...
    Ninadeng阅读 404评论 0 0
  • 一、JS介绍 1、什么是JS javaScripy = ECMAScript(js语法) + BOM - wind...
    Deathfeeling阅读 126评论 0 1
  • 今天去探索能吸引你的未知世界,与古老链接,将自己的所学发挥及创新。
    霞玛雅星际印记解读阅读 265评论 1 1
  • 相遇咋那么美那么惊心动魄 如果你不信 那是因为你还没遇到 谁说茫茫人海没有爱情 我侥幸偏偏遇到 那个字多么像荷花 ...
    花香一路阅读 326评论 1 11
  • 陌路花开应景红,百花闹春未峥嵘,我花待时运不济,不可贪恋盼春风。桃李不言争春意,梅菊亦可绽秋冬,凡事难尽泾渭明,率...
    返程无花果阅读 218评论 0 0