《左耳听风》-ARTS-打卡记录-第九周

Algorithm

 680. 验证回文字符串 Ⅱ 

我看leetcode这个题的难度为:简单,但却花了我好长时间,做的结果性能一般,被虐的生无可恋.

最开始采用的方法是脑子里最先蹦出来的,其实功能上没有问题,但耗时比较长,竟然被leetcode深深的鄙视了.

class Solution {
public:
    bool validPalindrome(string s) {
        string s1 = s;
        reverse(s.begin(),s.end());
        if(s1 == s)
        {
            return true;
        }
        else
        {
            for(int i = 0; i < s1.size(); i++)
            {
                string s2 = s1;
                s2.erase(i);
                string s3 = s2;
                reverse(s3.begin(),s3.end());
                if(s3 == s2)
                {
                    return true;
                }
            }
            return false;
        }
    }
};

自己分析了自己上面代码用时长的原因:主要是这里需要遍历整个字符串,题目中说字符串的最大长度是50000,整个效率确实太差了.而且想了下,只要有一处不符合条件,就可以排除它是回文字符串了.

又想到当前做的题是双指针类型的,就想到了用双指针去做.但这条路也走的很艰难.

class Solution {
public:
    bool validPalindrome(string s) {
        int i = 0;
        int j = s.size()-1;
        int diffCount = 0;
        while(i < j) //之前只写成i != j, "bddb"有问题
        {
            if(s[i] == s[j])
            {
                i++;
                j--;
            }
            else
            {
                if(s[i+1] == s[j])
                {
                    s.erase(i, 1);
                    //i++; //i应该不变
                    j--;
                    diffCount++;
                }
                else if(s[i] == s[j-1])
                {
                    s.erase(j, 1);
                    j--;
                    diffCount++;
                }
                else
                {
                    return false;
                }

            }
            if(diffCount > 1)
            {
                return false;
            }
        }
        return true;
    }
};

首先是自己把string的erase(i,1)一直写成erase(i),因为i是int类型的下标,这样s始终是空字符串,自己没有意识到,一直尝试,一直错.

后来是前面的i进行erase操作后,字符串s中i后面的部分会往前移动,这样i就直接指向了原来它后面的元素,此时在当前的条件语句中i不再需要进行++操作了,而j则需要进行--操作,因为它要找到原来它指向的元素;而当j进行erase操作后,在那个条件语句中i是不用动的,因为没有影响到它,j则需要往前移动,故需要--;

这还没完,在跑一个"aguokepatgbnvfqmgmlcupuufxoohdfpgjdmysgvhmvffcnqxjjxqncffvmhvgsymdjgpfdhooxfuupuculmgmqfvnbgtapekouga"例子时,上面的代码出现了问题,因为当i=20,j=79时,s[i+1] == s[j]和s[i] == s[j-1]都是满足的,但程序选择了前者,导致删除掉了i处的'c',导致剩下的字符串不再回文,让程序错认为不是回文字符串;

而实际上如果去除j位置的'u'后,剩余的字符串仍然是回文字符串.

于是做了如下的修改,不过感觉现在的代码还是不够高效和整洁,下一期把它好好优化下.

class Solution {
public:
    bool validPalindrome(string s) {
        int i = 0;
        int j = s.size()-1;
        int diffCount = 0;
        while(i < j) //之前只写成i != j, "bddb"有问题
        {
            if(s[i] == s[j])
            {
                i++;
                j--;
            }
            else
            {
                if(j - i > 3)
                {
                    if((s[i+1] == s[j]) && (s[i+2] == s[j-1]))
                    {
                        s.erase(i, 1);
                        //i++; //i应该不变
                        j--;
                        diffCount++;
                    }
                    else if((s[i] == s[j-1]) && (s[i+1] == s[j-2]))
                    {
                        s.erase(j, 1);
                        j--;
                        diffCount++;
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    if(s[i+1] == s[j])
                    {
                        s.erase(i, 1);
                        //i++; //i应该不变
                        j--;
                        diffCount++;
                    }
                    else if(s[i] == s[j-1])
                    {
                        s.erase(j, 1);
                        j--;
                        diffCount++;
                    }
                    else
                    {
                        return false;
                    } 
                }

            }
            if(diffCount > 1)
            {
                return false;
            }
        }
        return true;
    }
};

Review

How To Ask Questions The Smart Way(3/8)

Stack Overflow

Search, then ask on Stack Exchange

In recent years, the Stack Exchange community of sites has emerged as a major resource for answering technical and other questions and is even the preferred forum for many open-source projects.

Start with a Google search before looking at Stack Exchange; Google indexes it in real time. There's a very good chance someone has already asked a similar question, and the Stack Exchange sites are often near the top of the search results. If you didn't find anything through Google, search again on the specific site most relevant to your question (see below). Searching with tags can help narrow down the results.

If you still didn't find anything, post your question on the one site where it's most on-topic. Use the formatting tools, especially for code, and add tags that are related to the substance of your question (particularly the name of the programming language, operating system, or library you're having trouble with). If a commenter asks you for more information, edit your main post to include it. If any answer is helpful, click the up arrow to upvote it; if an answer gives a solution to your problem, click the check under the voting arrows to accept it as correct.

Stack Exchange has grown to over 100 sites, but here are the most likely candidates:

Super User is for questions about general-purpose computing. If your question isn't about code or programs that you talk to only over a network connection, it probably goes here.

Stack Overflow is for questions about programming.

Server Fault is for questions about server and network administration.

Several projects have their own specific sites, including Android, Ubuntu, TeX/LaTeX, and SharePoint. Check the Stack Exchange site for an up-to-date list.

Web and IRC forums

Your local user group, or your Linux distribution, may advertise a Web forum or IRC channel where newbies can get help. (In non-English-speaking countries newbie forums are still more likely to be mailing lists.) These are good first places to ask, especially if you think you may have tripped over a relatively simple or common problem. An advertised IRC channel is an open invitation to ask questions there and often get answers in real time.

In fact, if you got the program that is giving you problems from a Linux distribution (as is common today), it may be better to ask in the distro's forum/list before trying the program's project forum/list. The project's hackers may just say, “use our build”.

Before posting to any Web forum, check if it has a Search feature. If it does, try a couple of keyword searches for something like your problem; it just might help. If you did a general Web search before (as you should have), search the forum anyway; your Web-wide search engine might not have all of this forum indexed recently.

There is an increasing tendency for projects to do user support over a Web forum or IRC channel, with e-mail reserved more for development traffic. So look for those channels first when seeking project-specific help.

In IRC, it's probably best not to dump a long problem description on the channel first thing; some people interpret this as channel-flooding. Best to utter a one-line problem description in a way pitched to start a conversation on the channel.

As a second step, use project mailing lists

When a project has a development mailing list, write to the mailing list, not to individual developers, even if you believe you know who can best answer your question. Check the documentation of the project and its homepage for the address of a project mailing list, and use it. There are several good reasons for this policy:

  • Any question good enough to be asked of one developer will also be of value to the whole group. Contrariwise, if you suspect your question is too dumb for a mailing list, it's not an excuse to harass individual developers.

  • Asking questions on the list distributes load among developers. The individual developer (especially if he's the project leader) may be too busy to answer your questions.

  • Most mailing lists are archived and the archives are indexed by search engines. If you ask your question on-list and it is answered, a future querent could find your question and the answer on the Web instead of asking it again.

  • If certain questions are seen to be asked often, developers can use that information to improve the documentation or the software itself to be less confusing. But if those questions are asked in private, nobody has the complete picture of what questions are asked most often.

If a project has both a user” and a developer” (or hacker”) mailing list or Web forum, and you are not hacking on the code, ask in the user” list/forum. Do not assume that you will be welcome on the developer list, where they're likely to experience your question as noise disrupting their developer traffic.

However, if you are sure your question is non-trivial, and you get no answer in the user” list/forum for several days, try the developer” one. You would be well advised to lurk there for a few daysor at least review the last few days of archived messages, to learn the local folkways before posting (actually this is good advice on any private or semi-private list).

If you cannot find a project's mailing list address, but only see the address of the maintainer of the project, go ahead and write to the maintainer. But even in that case, don't assume that the mailing list doesn't exist. Mention in your e-mail that you tried and could not find the appropriate mailing list. Also mention that you don't object to having your message forwarded to other people. (Many people believe that private e-mail should remain private, even if there is nothing secret in it. By allowing your message to be forwarded you give your correspondent a choice about how to handle your e-mail.)

Use meaningful, specific subject headers

On mailing lists, newsgroups or Web forums, the subject header is your golden opportunity to attract qualified experts' attention in around 50 characters or fewer. Don't waste it on babble like Please help me” (let alone PLEASE HELP ME!!!!”; messages with subjects like that get discarded by reflex). Don't try to impress us with the depth of your anguish; use the space for a super-concise problem description instead.

One good convention for subject headers, used by many tech support organizations, is object - deviation”. The object” part specifies what thing or group of things is having a problem, and the deviation” part describes the deviation from expected behavior.

Stupid:

HELP! Video doesn't work properly on my laptop!

Smart:

X.org 6.8.1 misshapen mouse cursor, Fooware MV1005 vid. chipset

Smarter:

X.org 6.8.1 mouse cursor on Fooware MV1005 vid. chipset - is misshapen

The process of writing an object-deviation” description will help you organize your thinking about the problem in more detail. What is affected? Just the mouse cursor or other graphics too? Is this specific to the X.org version of X? To version 6.8.1? Is this specific to Fooware video chipsets? To model MV1005? A hacker who sees the result can immediately understand what it is that you are having a problem with and the problem you are having, at a glance.

More generally, imagine looking at the index of an archive of questions, with just the subject lines showing. Make your subject line reflect your question well enough that the next person searching the archive with a question similar to yours will be able to follow the thread to an answer rather than posting the question again.

If you ask a question in a reply, be sure to change the subject line to indicate that you're asking a question. A Subject line that looks like Re: test” or Re: new bug” is less likely to attract useful amounts of attention. Also, pare quotation of previous messages to the minimum consistent with cluing in new readers.

Do not simply hit reply to a list message in order to start an entirely new thread. This will limit your audience. Some mail readers, like mutt, allow the user to sort by thread and then hide messages in a thread by folding the thread. Folks who do that will never see your message.

Changing the subject is not sufficient. Mutt, and probably other mail readers, looks at other information in the e-mail's headers to assign it to a thread, not the subject line. Instead start an entirely new e-mail.

On Web forums the rules of good practice are slightly different, because messages are usually much more tightly bound to specific discussion threads and often invisible outside those threads. Changing the subject when asking a question in reply is not essential. Not all forums even allow separate subject lines on replies, and nearly nobody reads them when they do. However, asking a question in a reply is a dubious practice in itself, because it will only be seen by those who are watching this thread. So, unless you are sure you want to ask only the people currently active in the thread, start a new one.

Stack Overflow

搜索,然后 在 Stack Exchange 问。

近年来,Stack Exchange community 社区已经成为回答技术及其他问题的主要渠道,尤其是那些开放源码的项目。

因为 Google 索引是即时的,在看 Stack Exchange 之前先在 Google 搜索。有很高的机率某人已经问了一个类似的问题,而且 Stack Exchange 网站们往往会是搜索结果中最前面几个。如果你在 Google 上没有找到任何答案,你再到特定相关主题的网站去找。用标签(Tag)搜索能让你更缩小你的搜索结果。

Stack Exchange 已经成长到超过一百个网站,以下是最常用的几个站:

  • Super User 是问一些通用的电脑问题,如果你的问题跟代码或是写程序无关,只是一些网络连线之类的,请到这里。
  • Stack Overflow 是问写程序有关的问题。
  • Server Fault 是问服务器和网管相关的问题。

网站和IRC论坛

本地的使用者群组(user group),或者你所用的 Linux 发行版本也许正在宣传他们的网页论坛或 IRC 频道,并提供新手帮助(在一些非英语国家,新手论坛很可能还是邮件列表), 这些地方是开始提问的好首选,特别是当你觉得遇到的也许只是相对简单或者很普通的问题时。经过宣传的 IRC 频道是公开欢迎提问的地方,通常可以即时得到回应。

事实上,如果程序出的问题只发生在特定 Linux 发行版提供的版本(这很常见),最好先去该发行版的论坛或邮件列表中提问,再到程序本身的论坛或邮件列表提问。(否则)该项目的黑客可能仅仅回复 "用**我们的**版本"。

在任何论坛发文以前,先确认一下有没有搜索功能。如果有,就试着搜索一下问题的几个关键词,也许这会有帮助。如果在此之前你已做过通用的网页搜索(你也该这样做),还是再搜索一下论坛,搜索引擎有可能没来得及索引此论坛的全部内容。

通过论坛或 IRC 频道来提供使用者支持服务有增长的趋势,电子邮件则大多为项目开发者间的交流而保留。所以最好先在论坛或 IRC 中寻求与该项目相关的协助。

第二步,使用项目邮件列表

当某个项目提供开发者邮件列表时,要向列表而不是其中的个别成员提问,即使你确信他能最好地回答你的问题。查一查项目的文件和首页,找到项目的邮件列表并使用它。有几个很好的理由支持我们采用这种办法:

  • 任何好到需要向个别开发者提出的问题,也将对整个项目群组有益。反之,如果你认为自己的问题对整个项目群组来说太愚蠢,也不能成为骚扰个别开发者的理由。
  • 向列表提问可以分散开发者的负担,个别开发者(尤其是项目领导人)也许太忙以至于没法回答你的问题。
  • 大多数邮件列表都会被存档,那些被存档的内容将被搜索引擎索引。如果你向列表提问并得到解答,将来其它人可以通过网页搜索找到你的问题和答案,也就不用再次发问了。
  • 如果某些问题经常被问到,开发者可以利用此信息来改进说明文件或软件本身,以使其更清楚。如果只是私下提问,就没有人能看到最常见问题的完整场景。

如果一个项目既有"使用者" 也有"开发者"(或"黑客")邮件列表或论坛,而你又不会动到那些源代码,那么就向"使用者"列表或论坛提问。不要假设自己会在开发者列表中受到欢迎,那些人多半会将你的提问视为干扰他们开发的噪音。

然而,如果你**确信**你的问题很特别,而且在"使用者" 列表或论坛中几天都没有回复,可以试试前往"开发者"列表或论坛发问。建议你在张贴前最好先暗地里观察几天以了解那里的行事方式(事实上这是参与任何私有或半私有列表的好主意)

如果你找不到一个项目的邮件列表,而只能查到项目维护者的电子邮件地址,尽管向他发信。即使是在这种情况下,也别假设(项目)邮件列表不存在。在你的电子邮件中,请陈述你已经试过但没有找到合适的邮件列表,也提及你不反对将自己的邮件转发给他人(许多人认为,即使没什么秘密,私人电子邮件也不应该被公开。通过允许将你的电子邮件转发他人,你给了相应人员处置你邮件的选择)。

使用有意义且描述明确的标题

在邮件列表、新闻群组或论坛中,大约50字以内的标题是抓住资深专家注意力的好机会。别用喋喋不休的帮帮忙跪求(更别说救命啊!!!!这样让人反感的话,用这种标题会被条件反射式地忽略)来浪费这个机会。不要妄想用你的痛苦程度来打动我们,而是在这点空间中使用极简单扼要的描述方式来提出问题。

一个好标题范例是目标 -- 差异式的描述,许多技术支持组织就是这样做的。在目标部分指出是哪一个或哪一组东西有问题,在差异部分则描述与期望的行为不一致的地方。

蠢问题:救命啊!我的笔电不能正常显示了!

聪明问题:X.org 6.8.1的鼠标游标会变形,某牌显卡 MV1005 芯片组。

更聪明问题:X.org 6.8.1的鼠标游标,在某牌显卡 MV1005 芯片组环境下 - 会变形。

编写目标 -- 差异 式描述的过程有助于你组织对问题的细緻思考。是什么被影响了? 仅仅是鼠标游标或者还有其它图形?只在 X.org 的 X 版中出现?或只是出现在6.8.1版中? 是针对某牌显卡芯片组?或者只是其中的 MV1005 型号? 一个黑客只需瞄一眼就能够立即明白你的环境****你遇到的问题。

总而言之,请想像一下你正在一个只显示标题的存档讨论串(Thread)索引中查寻。让你的标题更好地反映问题,可使下一个搜索类似问题的人能够关注这个讨论串,而不用再次提问相同的问题。

如果你想在回复中提出问题,记得要修改内容标题,以表明你是在问一个问题, 一个看起来像 Re: 测试 或者 Re: 新bug 的标题很难引起足够重视。另外,在不影响连贯性之下,适当引用并删减前文的内容,能给新来的读者留下线索。

对于讨论串,不要直接点击回复来开始一个全新的讨论串,这将限制你的观众。因为有些邮件阅读程序,比如 mutt ,允许使用者按讨论串排序并通过折叠讨论串来隐藏消息,这样做的人永远看不到你发的消息。

仅仅改变标题还不够。mutt 和其它一些邮件阅读程序还会检查邮件标题以外的其它信息,以便为其指定讨论串。所以宁可发一个全新的邮件。

在网页论坛上,好的提问方式稍有不同,因为讨论串与特定的信息紧密结合,并且通常在讨论串外就看不到里面的内容,故通过回复提问,而非改变标题是可接受的。不是所有论坛都允许在回复中出现分离的标题,而且这样做了基本上没有人会去看。不过,通过回复提问,这本身就是暧昧的做法,因为它们只会被正在查看该标题的人读到。所以,除非你**只想**在该讨论串当前活跃的人群中提问,不然还是另起炉灶比较好。


Tips

走出自己的舒服圈。并不只是多看几页书,看几个视频是学习,从项目中了解自己之前不知道的,别人是如何做的,了解全貌,这样学到的东西更多。
1.系统全貌:比如我做的这一块在总体中处于什么位置,和别的是怎么交互的,我需要怎么去和他们联调和测试。
2.对外暴露哪些接口呢?比如客户端中一些菜单可以看做是用户手动调用的接口。
3.项目经理管理项目:去建立版本管理的工具,去把资源共享进去,去每天开早会了解项目进展,架构是他的事吗?
4.人人都是产品经理,想着用户会怎么用,如何让用户用着顺手,哪些需要在文档中去说明


Share

07 | 解决了很多技术问题,为什么你依然在“坑”里? 

——<10x程序员工作法> 郑烨
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodingLife99

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值