Leetcode - Generate Parentheses

Paste_Image.png

My code:

import java.util.ArrayList;
import java.util.List;

public class Solution {
    public List<String> generateParenthesis(int n) {
        ArrayList<String> result = new ArrayList<String>();
        if (n <= 0)
            return result;
        String s = "(";
        generateParenthesis(1, 0, n, result, s);
        return result;
    }
    
    private void generateParenthesis(int left, int right, int total, ArrayList<String> result, String s) {
        if (left == right && left + right == 2 * total) {
            result.add(s);
            return;
        }
        if (left < total) {
            generateParenthesis(left + 1, right, total, result, s + '(');
        }
        if (right < left)
            generateParenthesis(left, right + 1, total, result, s + ')');
    }
    
    public static void main(String[] args) {
        Solution test = new Solution();
        System.out.println(test.generateParenthesis(3));
    }
}

My test result:

Paste_Image.png

这次作业其实挺简单的,不知道自己为什么会卡住,其实看了答案,自己已经很接近了。。。可能分心了吧,肚子又有点疼,很那做下去了。一般分心了之后,就再也难重新集中注意力做这道题目了。
说说之前花了大量的时间研究的问题吧。

String 到底他妈是什么东西,存在了哪里。
他的本质,源码里规定的很清楚。
final char[]. 是常量型的字符数组。一旦初始化就不能再被改变了。所以一般是存储在常量池中。
那么,常量池又是什么东西呢?
常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。
好像有些废话。但的确是这个意思。string存在于常量池中,而常量池是否存在于堆中,我不清楚。
string一般有两种初始化方式。
String s = new String("myString");
String s = "myString";

第一个初始化出来的不是字符串常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。
而第二个初始化出来的是字符串常量,存在了常量池中。

第一种方式通过关键字new定义过程:在程序编译期,编译程序先去字符串常量池检查,是否存在“myString”,如果不存在,则在常量池中开辟一个内存空间存放“myString”;如果存在的话,则不用重新开辟空间,保证常量池中只有一个“myString”常量,节省内存空间。然后在内存堆中开辟一块空间存放new出来的String实例,在栈中开辟一块空间,命名为“s1”,存放的值为堆中String实例的内存地址,这个过程就是将引用s1指向new出来的String实例。

第二种方式直接定义过程:在程序编译期,编译程序先去字符串常量池检查,是否存在“myString”,如果不存在,则在常量池中开辟一个内存空间存放“myString”;如果存在的话,则不用重新开辟空间。然后在栈中开辟一块空间,命名为“s1”,存放的值为常量池中“myString”的内存地址。
这是摘抄自网上的一段话。讲的还有些道理。
然后说说,
StringBuilder 和 StringBuffer
他们和string的最大不同是,
他们都是 char[]. 即初始化后可变的,
String、StringBuffer和StringBuilder在本质上都是字符数组,不同的是,在进行连接操作时,String每次返回一个新的String实例,而StringBuffer和StringBuilder的append方法直接返回this,所以这就是为什么在进行大量字符串连接运算时,不推荐使用String,而推荐StringBuffer和StringBuilder。
StringBuffer在方法前加了一个synchronized修饰,起到同步的作用,可以在多线程环境使用。为此付出的代价就是降低了执行效率。因此,如果在多线程环境可以使用StringBuffer进行字符串连接操作,单线程环境使用StringBuilder,它的效率更高。

下面给两个链接,文章写得不错。
http://my.oschina.net/xiaohui249/blog/170013
http://blog.csdn.net/ithomer/article/details/7300948

**
总结: string, 常量池,初始化, StringBuilder, StringBuffer
**

Anyway, Good luck, Richardo!

My code

public class Solution {
    public List<String> generateParenthesis(int n) {
        ArrayList<String> ret = new ArrayList<String>();
        if (n <= 0)
            return ret;
        dfs(n, n, "", ret);
        return ret;
    }
    
    private void dfs(int left, int right, String s, ArrayList<String> ret) {
        if (left > right)
            return;
        else if (left == 0 && right == 0) {
            ret.add(s);
            return;
        }
        if (left > 0) {
            dfs(left - 1, right, s + "(", ret);
        }
        if (right > 0) {
            dfs(left, right - 1, s + ")", ret);
        }
    }
}

这道题木没有做出来。奇怪的是,第一次竟然也没有做出来。
为什么呢?因为典型的backtracking,
是用一个 for 循环,然后探索过的,会删掉。
但是这边的左括号,删掉一次后,第二次还会再加去,也可以看出,他根本没有用for循环,所以我思维定式了,导致用for循环来思考问题而得不出答案。
String s = "abc";
s += "d";
此时 s的内存地址已经发生了改变。

StringBuilder s = new StringBuilder("abc");
s.append("d");
s的内存地址并未改变。stringbuilder 是 Mutable的。加上"d"后,将自己的地址返回。

Anyway, Good luck, Richardo!

My code:

public class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> ret = new ArrayList<String>();
        if (n <= 0) {
            return ret;
        }
        
        helper(0, 0, n, "", ret);
        return ret;
    }
    
    private void helper(int left, int right, int n, String s, List<String> ret) {
        if (left < right) {
            return;
        }
        if (left == n && right < n) {
            helper(left, right + 1, n, s + ")", ret);
            return;
        }
        else if (right == n) {
            ret.add(s);
            return;
        }
        else if (left == right) {
            helper(left + 1, right, n, s + "(", ret);
        }
        else {
            helper(left + 1, right, n, s + "(", ret);
            helper(left, right + 1, n, s + ")", ret);
        }
    }
    
}

差不多的想法。思想起源于, 一个 valid parenthesis, 只有 left 始终 >= right, 并且,最终时刻, left == right
可以根据这个想法,来构造 valid parenthesis,保证 left 始终 >= right, 并且在最后, left = right = n

Anyway, Good luck, Richardo! -- 09/17/2016

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

推荐阅读更多精彩内容

  • 写着写着发现简书提醒我文章接近字数极限,建议我换一篇写了。 建议52:推荐使用String直接量赋值 一般对象都是...
    我没有三颗心脏阅读 1,348评论 2 4
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,639评论 18 399
  • 1. 面向对象的特征有哪些方面? 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方...
    程序熊大阅读 4,374评论 6 74
  • 和闺蜜的心电感应总是很灵,最近情绪低落的我被她召唤去她家陪她度过厨娘时光,互打鸡血,生活有再多的不如意也要支撑着...
    武汉咖啡猫阅读 500评论 0 0
  • 如果我有一套大房子,其中有一间是这样的:它是朝阳的,带阳台,落地窗。房间面宽可以小,但进深要大。我在里面培植池塘和...
    细腰阅读 204评论 0 0