Hard-题目9:301. Remove Invalid Parentheses

本文介绍了一种使用深度优先搜索(DFS)解决LeetCode上“去除无效括号”问题的方法。该问题要求移除最少数量的无效括号使输入字符串有效,并返回所有可能的结果。文章详细解释了解决方案的思路,并提供了Java实现的源代码。

题目原文:
Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results.

Note: The input string may contain letters other than the parentheses ( and ).

Examples:
“()())()” -> [“()()()”, “(())()”]
“(a)())()” -> [“(a)()()”, “(a())()”]
“)(” -> [“”]
题目大意:
给出一个括号和字母的字符串,其中有一些括号是失配的,求出所有去掉失配括号的解。
例如:
“()())()” -> [“()()()”, “(())()”]
(这个例子中多了一个右括号,但有两种去掉右括号的方式,故最后答案有2个解)
题目分析:
参考别人博客的解法,使用DFS求解。
首先定义“失配度”,代表字符串或其子串中失配括号的个数,博客中给出的解法大多使用了堆栈,其实不用,只用一个整形(相当于堆栈长度)维护即可,遇到左括号+1,遇到右括号如果长度不为0则减1,否则失配度+1,扫完字符串后加上这个长度(失配左括号数)。
然后从源字符串开始搜索,遍历字符串,如果当前字符串不是括号则跳过,否则计算去掉这个括号的失配度,如果比当前失配度小1,则继续向下搜索这个子串(说明继续寻找可以找到解),如果比当前失配度大1,则说明去掉这个括号不能得到解(因为继续搜索下去即使找到解也去掉了原来已经匹配的括号!),如果失配度=0则找到解。
这里需要用一个HashSet记录所有搜索过的字符串,如果一个字符串已经搜索过则不再搜索。这是个很重要的剪枝,否则会超时。因为对”((((((((((((((((((((((((((())”这个串,如果不做这个处理,第一层就会对每个去掉左括号的子串搜索一遍,而它们是一样的,可想而知有多少重复操作!
源码:(language:java)

public class Solution {
    HashSet<String> visited = new HashSet<String>();
    private int getMisses(String s) { // calculate the missing num of parentheses
        int parentheses = 0;
        int miss = 0;
        for(int i = 0;i<s.length();i++) {
            if(s.charAt(i) == '(')
                parentheses++;
            else if(s.charAt(i) == ')'){
                if(parentheses==0) 
                    miss++;
                else
                    parentheses--;
            }
        }
        miss+=parentheses;
        return miss;
    }
    private void dfs(List<String> list, String s, int miss) {
        if(miss == 0) 
            list.add(s);
        else {
            for(int i = 0;i<s.length();i++) {
                String nextStr = removeCharAt(s, i); 
                if(!visited.contains(nextStr)) {
                    visited.add(nextStr);
                    int nextMiss = getMisses(nextStr);
                    if(nextMiss<miss)
                        dfs(list, nextStr, nextMiss);
                }
            }
        }
    }
    private String removeCharAt(String s, int pos) {
          return s.substring(0, pos) + s.substring(pos + 1);
    }

    public List<String> removeInvalidParentheses(String s) {
        List<String> list = new ArrayList<String>();
        dfs(list,s,getMisses(s));
        return list;

    }
}

成绩:
23ms,beats 57.67%,众数3ms,13.37%
Cmershen的碎碎念:
3ms的办法也用到了递归,但不知道有没有回溯,在discuss https://leetcode.com/discuss/81478/easy-short-concise-and-fast-java-dfs-3-ms-solution中有介绍,但满篇E文让我懒得看,而博客中的中文分析大多与上述解法类似(我也是基于中文博客做的),还有一种基于bfs的,更慢且不易理解。

解释这些日志是什么意思,从网易邮箱下载的PDF通过文件预览打开的是乱码 Line 3559: 10-09 11:48:55.896 3482 4703 I .zhuoyi.browse: NotifyOhSurfaceDestroyed: oh surface is destroyed Line 3561: 10-09 11:48:55.896 3482 4703 I .zhuoyi.browse: BnTransactSurfaceDelegator::SetClient 0 Line 3573: 10-09 11:48:55.898 3482 3508 I ZrHung.AppEyeUiProbe: not watching, wait. Line 3705: 10-09 11:48:55.935 3482 3582 W .zhuoyi.browse: QueueBuffer: go to releaseBuffer solt: 0 sharedBufferMode: 0 hasClient: 0 Line 3712: 10-09 11:48:55.935 3482 3582 E .zhuoyi.browse: SendMessage: SurfaceDelegator client is nullptr Line 3713: 10-09 11:48:55.935 3482 3582 E BufferQueueProducer: dequeueBuffer: ProducerSurfaceDelegator dequeueBuffer failed, error=-1, slot:1, hasNewBuffer:0 Line 3739: 10-09 11:48:55.937 3482 3582 W .zhuoyi.browse: QueueBuffer: go to releaseBuffer solt: 1 sharedBufferMode: 0 hasClient: 0 Line 3753: 10-09 11:48:55.941 3482 3582 E .zhuoyi.browse: SendMessage: SurfaceDelegator client is nullptr Line 3754: 10-09 11:48:55.941 3482 3582 E BufferQueueProducer: dequeueBuffer: ProducerSurfaceDelegator dequeueBuffer failed, error=-1, slot:3, hasNewBuffer:0 Line 3763: 10-09 11:48:55.943 3482 3582 W .zhuoyi.browse: QueueBuffer: go to releaseBuffer solt: 3 sharedBufferMode: 0 hasClient: 0 Line 3764: 10-09 11:48:55.944 3482 3482 E RtgSchedIpcFile: RtgSchedIpcFile SearchRtgForTid failed, errno = 22 (Invalid argument) Line 3764: 10-09 11:48:55.944 3482 3482 E RtgSchedIpcFile: RtgSchedIpcFile SearchRtgForTid failed, errno = 22 (Invalid argument) Line 3765: 10-09 11:48:55.944 3482 3482 E RtgSchedIpcFile: RtgSchedIpcFile SearchRtgForTid failed, errno = 22 (Invalid argument) Line 3765: 10-09 11:48:55.944 3482 3482 E RtgSchedIpcFile: RtgSchedIpcFile SearchRtgForTid failed, errno = 22 (Invalid argument) Line 3766: 10-09 11:48:55.945 3482 3482 I HwViewRootImpl: removeInvalidNode all the node in jank list is out of time Line 3766: 10-09 11:48:55.945 3482 3482 I HwViewRootImpl: removeInvalidNode all the node in jank list is out of time Line 3767: 10-09 11:48:55.945 3482 3482 I WindowManager: trimMemory level: 20 Line 3767: 10-09 11:48:55.945 3482 3482 I WindowManager: trimMemory level: 20 Line 3768: 10-09 11:48:55.946 3482 3482 I hwschromium-21311: [INFO:adaptive_relayout_impl.cc(27)] enter ShouldDoAdaptiveRelayout Line 3768: 10-09 11:48:55.946 3482 3482 I hwschromium-21311: [INFO:adaptive_relayout_impl.cc(27)] enter ShouldDoAdaptiveRelayout Line 3769: 10-09 11:48:55.946 3482 3482 I hwschromium-21311: [INFO:adaptive_relayout_impl.cc(37)] exit ShouldDoAdaptiveRelayout, should[0] Line 3769: 10-09 11:48:55.946 3482 3482 I hwschromium-21311: [INFO:adaptive_relayout_impl.cc(37)] exit ShouldDoAdaptiveRelayout, should[0] Line 3770: 10-09 11:48:55.946 3482 3482 I ViewRootImpl[HomeActivity]: ViewUI windowFocusChanged: hasFocus false inTouchMode true Line 3770: 10-09 11:48:55.946 3482 3482 I ViewRootImpl[HomeActivity]: ViewUI windowFocusChanged: hasFocus false inTouchMode true Line 3774: 10-09 11:48:55.946 3482 3482 I InsetsSourceConsumer: ViewUI_insets mSourceControl is null notifyControlRevoked type: 1 Line 3774: 10-09 11:48:55.946 3482 3482 I InsetsSourceConsumer: ViewUI_insets mSourceControl is null notifyControlRevoked type: 1 Line 3776: 10-09 11:48:55.946 3482 3482 I InsetsSourceConsumer: ViewUI_insets mSourceControl is null notifyControlRevoked type: 0 Line 3776: 10-09 11:48:55.946 3482 3482 I InsetsSourceConsumer: ViewUI_insets mSourceControl is null notifyControlRevoked type: 0 Line 3777: 10-09 11:48:55.946 3482 3482 I InsetsController: ViewUI_insets onControlsChanged, showTypes:0 hideTypes:0 Line 3777: 10-09 11:48:55.946 3482 3482 I InsetsController: ViewUI_insets onControlsChanged, showTypes:0 hideTypes:0 Line 3778: 10-09 11:48:55.946 3482 3482 I ViewRootImpl[HomeActivity]: ViewUI handleWindowFocusChanged: hasWindowFocus false inTouchMode true Line 3778: 10-09 11:48:55.946 3482 3482 I ViewRootImpl[HomeActivity]: ViewUI handleWindowFocusChanged: hasWindowFocus false inTouchMode true Line 3779: 10-09 11:48:55.946 3482 3482 E HomeActivity: onWindowFocusChanged hasFocus:false, initialized:true Line 3779: 10-09 11:48:55.946 3482 3482 E HomeActivity: onWindowFocusChanged hasFocus:false, initialized:true Line 3780: 10-09 11:48:55.946 3482 3482 I DecorView: anco-don&#39;t need to updateMiniFreeFormCoverViewVisible. Line 3780: 10-09 11:48:55.946 3482 3482 I DecorView: anco-don&#39;t need to updateMiniFreeFormCoverViewVisible. Line 3782: 10-09 11:48:55.949 3482 3482 E RtgSchedIpcFile: RtgSchedIpcFile SearchRtgForTid failed, errno = 22 (Invalid argument) Line 3782: 10-09 11:48:55.949 3482 3482 E RtgSchedIpcFile: RtgSchedIpcFile SearchRtgForTid failed, errno = 22 (Invalid argument) Line 3783: 10-09 11:48:55.949 3482 3482 E RtgSchedIpcFile: RtgSchedIpcFile SearchRtgForTid failed, errno = 22 (Invalid argument) Line 3783: 10-09 11:48:55.949 3482 3482 E RtgSchedIpcFile: RtgSchedIpcFile SearchRtgForTid failed, errno = 22 (Invalid argument) Line 3784: 10-09 11:48:55.949 3482 3482 E RtgSchedIpcFile: RtgSchedIpcFile SearchRtgForTid failed, errno = 22 (Invalid argument) Line 3784: 10-09 11:48:55.949 3482 3482 E RtgSchedIpcFile: RtgSchedIpcFile SearchRtgForTid failed, errno = 22 (Invalid argument) Line 3787: 10-09 11:48:55.949 3482 3482 E RtgSchedIpcFile: RtgSchedIpcFile SearchRtgForTid failed, errno = 22 (Invalid argument) Line 3787: 10-09 11:48:55.949 3482 3482 E RtgSchedIpcFile: RtgSchedIpcFile SearchRtgForTid failed, errno = 22 (Invalid argument)
最新发布
10-14
### `LOGLIMIT` 日志 ```plaintext Line 3096: 10-09 11:48:55.793 3482 3482 E LOGLIMIT: process com.zhuoyi.browser drop 39 lines, from time:1759981730 to time:1759981735, threshold:13050 ``` 此日志表明 `com.zhuoyi.browser` 进程的日志输出达到了限制,有 39 行日志被丢弃,丢弃的日志时间范围从 `1759981730` 到 `1759981735`,阈值为 `13050`。这可能会掩盖一些与 PDF 预览乱码相关的关键错误信息,影响问题的排查[^1]。 ### `InputEvent` 日志 ```plaintext Line 3097: 10-09 11:48:55.793 3482 3482 I InputEvent: ViewUI (145,2724):(145,2724)0-1-0 ``` `InputEvent` 日志与用户的输入事件有关,这里记录了在坐标 `(145, 2724)` 处发生的输入事件,`0-1-0` 可能是该事件的特定编码。在 PDF 预览乱码的场景下,这些输入事件可能用于排查是否因为误操作(如在下载或预览过程中进行了不恰当的触摸、按键等操作)影响了文件的正常预览[^1]。 ### `DecorView` 日志 ```plaintext Line 3102: 10-09 11:48:55.794 3482 3482 I DecorView: anco-don&#39;t need to updateMiniFreeFormCoverViewVisible. ``` `DecorView` 是 Android 系统中视图层次结构的顶层视图,包含状态栏、标题栏等。此日志表示不需要更新 `MiniFreeFormCoverView` 的可见性。在 PDF 预览乱码问题中,这可能与视图的布局或绘制有关,如果视图布局异常,可能会导致 PDF 显示异常[^1]。 ### `hwschromium` 相关日志 ```plaintext Line 3186: 10-09 11:48:55.839 3482 3482 E hwschromium-21311: [ERROR:browser_url_handler_impl.cc(175)] AddChannelKeyForSearchEngine url has no host ``` 这是 `hwschromium` 模块的错误日志,表明在执行 `AddChannelKeyForSearchEngine` 操作时,URL 没有主机名。虽然这可能与 PDF 预览乱码没有直接关联,但可能反映出浏览器内核在处理某些操作时存在问题,可能间接影响 PDF 的正常预览[^1]。 ### `Activity` 相关日志 ```plaintext Line 3214: 10-09 11:48:55.841 3482 3482 I Activity: Finishing self: token=android.os.BinderProxy@bc404c7, ident=44222482, component=com.ddu.browser.oversea.HomeActivity ``` 该日志表示 `com.ddu.browser.oversea.HomeActivity` 活动正在自我结束。在 PDF 预览过程中,如果活动异常结束,可能会影响 PDF 的正常加载和显示,导致预览乱码[^1]。 ### `OomAdjuster` 相关日志 ```plaintext Line 3482: 10-09 11:48:55.879 354 420 I OomAdjuster: setProcessGroup 3482 to 0:(AdjType=cch-rec, AdjTarget=null) ``` `OomAdjuster` 用于调整进程的内存使用情况,此日志表示将进程 ID 为 `3482` 的进程组设置为 `0`,调整类型为 `cch-rec`。如果进程内存不足,可能会导致 PDF 加载不完整,从而出现预览乱码的情况[^1]。 ### `system_server` 相关日志 ```plaintext Line 3494: 10-09 11:48:55.883 354 420 W system_server: FileWrite open /proc/3482/task/3600/static_vip fail errno(2)! ``` 这是 `system_server` 发出的警告日志,表明尝试打开 `/proc/3482/task/3600/static_vip` 文件失败,错误码为 `2`(通常表示文件或目录不存在)。这可能会影响进程的某些配置或状态,进而影响 PDF 的预览[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值