求解性思维与验证性思维

 题目分析:  Given a list of unique words. Find all pairs of distinct indices (i, j) in the given list,   so that the concatenation of the two words, i.e. words[i] + words[j] is a palindrome.

 Example 1:
 Given words = ["bat", "tab", "cat"]
 Return [[0, 1], [1, 0]]
 The palindromes are ["battab", "tabbat"]
 Example 2:
 Given words = ["abcd", "dcba", "lls", "s", "sssll"]
 Return [[0, 1], [1, 0], [3, 2], [2, 4]]
  The palindromes are ["dcbaabcd", "abcddcba", "slls", "llssssll"]
/**
 * 论求解性思维与验证性思维
 *
 * 本题很直观的想法是验证性思维:一一去验证每个可能性,
 * 时间复杂度O(n^2*k),n为字符串的数量,k为字符串的长度
 * 显然这种方法对于n不是很大的情况比较适用,当n比较大时效率就太低
 *
 * 如果采用求解性思维,那么我们只需要找对于每个字符串与其可以构成回文字符串的字符串
 * 是否存在即可,时间复杂度O(n * k^2 ),对于k不是很大的情况下比较适用,当k太大是效率
 * 也是比较低的。通过提交发现本题适合第二种情况
 *
 * 总结:求解性思维与验证性思维是算法中常见的两位基本思维方式,对于不同的题目两种算法
 * 的效率也是不同的。验证性思维与二分法的结合是经常出现的一个知识点,一般情况下如果有
 * 好的求解方案,求解性思维的效率是很高的。当然具体题目具体分析
 *
 * ps(正向思维与逆向思维也是两种常见的思想)
 **/

class Solution {
public:
    bool ispalindrome(string &st)
    {
        int u = 0, v = st.size() - 1;
        while(u <= v)
        {
            if(st[u] != st[v]) break;
            ++u;
            --v;
        }
        if(u > v) return true;
        else return false;
    }
    vector<vector<int>> palindromePairs(vector<string>& words) {
        vector<vector<int>> ans;
        int tans[2];
        unordered_map<string, int> ump;
        for(size_t i = 0; i != words.size(); ++i)
        {
            string st = words[i];
            reverse(st.begin(), st.end());
            ump[st] = i;
        }

        for(size_t i = 0; i != words.size(); ++i)
        {
            if(ispalindrome(words[i]) && ump.find("") != ump.end() && ump[""] != i)
            {
                tans[0] = i;
                tans[1] = ump[""];
                ans.push_back(vector<int>(tans, tans + 2));
                tans[0] = ump[""];
                tans[1] = i;
                ans.push_back(vector<int>(tans, tans + 2));
            }
        }

        for(size_t i = 0; i != words.size(); ++i)
        {
            if(ump.find(words[i]) != ump.end() && ump[words[i]] != i)
            {
                tans[0] = i;
                tans[1] = ump[words[i]];
                ans.push_back(vector<int>(tans, tans + 2));
            }

            for(size_t j = 1; j < words[i].size(); ++j)
            {
                string left, right;
                left = words[i].substr(0, j);
                right = words[i].substr(j, words[i].size() - j);

                if(ispalindrome(right) && ump.find(left) != ump.end())
                {
                    tans[0] = i;
                    tans[1] = ump[left];
                    ans.push_back(vector<int>(tans, tans + 2));
                }
                if(ispalindrome(left) && ump.find(right) != ump.end())
                {
                    tans[0] = ump[right];
                    tans[1] = i;
                    ans.push_back(vector<int>(tans, tans + 2));
                }
            }
        }
        return ans;
    }
};
时间: 2024-10-25 00:20:45

求解性思维与验证性思维的相关文章

实验二 顺序结构程序设计(验证性实验

安徽工程大学 Python程序设计 实验报告 班级   物流192   姓名 张羽  学号3190505221 成绩 日期     2020.3.22      指导老师       修宇 实验二 顺序结构程序设计(验证性实验) [实验目的] (1)掌握数据的输入输出的方法: (2)熟悉顺序结构程序中语句的执行过程: (3)掌握顺序结构程序的设计方法. [实验条件] PC机或者远程编程环境 [实验内容] 1.完成三个编程题.( python123) (1)计算圆面积的计算 S 问题描述: 根据圆

Python程序设计实验报告二:顺序结构程序设计(验证性实验)

安徽工程大学 Python程序设计 实验报告 班级   物流192   姓名  冯非凡  学号3190505208 成绩 日期     2020.3.22    指导老师       修宇 实验二 顺序结构程序设计(验证性实验) [实验目的] (1)掌握数据的输入输出的方法: (2)熟悉顺序结构程序中语句的执行过程: (3)掌握顺序结构程序的设计方法. [实验条件] PC机或者远程编程环境 [实验内容] 1.完成三个编程题.( python123) (1)计算圆面积的计算 S 问题描述: 根据圆

4星|《学会提问》:批判性思维入门,常见思维误区与诡辩技巧解析

? 主要内容是如何使用批判性思维来做判断.辩论.逐个讲解判断与辩论中的常见思维误区与诡辩技巧,有案例,有练习. 我总结书中比较重要的技巧是下面几个: 1:需要经常带着抬杠的态度去看待媒体与他人的观点,也需要提醒自己接受他人的抬杠: 2:找到对方的结论与证据: 3:避免“晕轮效应”(halo effect): 4:避免“确认性偏见”(confirmation bias): 5:避免“以偏概全谬误”: 6:需要注意具体生动的案例诉诸我们的情感,会干扰我们的判断: 7:科学研究是我们获得证据的一个最好

摆脱技术思维,转向产品思维——寻找“万能”IDC的苦恼

背景:最近在新产品的开发任务完成后一直在为寻找好的IDC和优质的托管服务忙碌.需求源自于我们重点要解决之前老版产品面临的国内外用户访问速度慢甚至连接不上的问题.除去架构技术上使用高性能.可扩展的方案,针对目前的并发量和数据量而言只要能保证网络质量的优质就可以达到较好的用户体验. 首先我们的产品平台数据需要较强的一致性.高可用性,而且很多是动态数据.根据CAP理论,我们首先否决了分布式部署的方案,一是自己和团队对分布式技术的拿捏还欠缺,二是从开发周期上来说不允许我们有太复杂的研究和设计.所以就将目

僵固式思维 OR 成长式思维

有意无意中,看到这样的一篇文章,觉得非常富有正能量,而且也比较有同感.而且,不仅仅对于职场暂时失落或者失意的人有帮助,就是对学生,也一样的.故特分享,以共勉之. 我想每个新人进入职场之后都会遇到的第一个问题是发现自己什么都做不好. 这个时候是很挫败的,因为会发现自己连邮件也不会写电话也不会打.从学校带出来的良好的自我感觉被瞬间摧毁,每天都在焦虑不安.我也曾经要做一个公司产品的简介 PPT,从来没试过对接客户,不知道如何才能做出高大上的 PPT.于是一直在拖延,选择性忽略这项工作去忙别的事情.即使

从两层设计思维转向三层设计思维

传统的两层编程思维是这样的 界面的设计.业务逻辑的设计.数据库的链接都放在一起实现. 总体来说,两层的编程主要有如下特点 数据库访问和用户类型判断逻辑放在一起实现. 用户界面层直接调用数据访问实现.  用户界面层直接调用数据访问实现. 这种结构存在着很多局限性,比如:一旦用户的需求发生变化,应用程序都需要进行大量修改,甚至需要重新开发,给系统的维护和升级带来了极大的不便:用户界面层直接访问数据库,会带来很多安全隐患.为了克服两层结构的局限性提出了三层结构. 而所谓三层体系结构,是在客户端与数据库

黄锦宣:用户思维弥补了产品思维运营的缺陷

我家乡是汕尾的,在我家乡有一种小吃比较出名,基本所有汕尾人都喜欢吃的"小米",呵呵,这里说的小米非雷军的小米,人要是吃手机了,这个比名小吃更能出名.扯远了.汕尾的小吃"小米"相当于饺子,可是它的皮不是面粉做的,是薯粉做的,所以"小米"还有个别名叫薯粉饺. 汕尾的"小米"可谓是远近闻名,一笼小米在加上一碗牛肉饼汤,那是我的至爱啊!但是随着这些年的物价上涨,以前一笼三块钱的"小米"现在一笼要十元了,以前十元可以

6、Java并发性和多线程-并发性与并行性

以下内容转自http://tutorials.jenkov.com/java-concurrency/concurrency-vs-parallelism.html(使用谷歌翻译): 术语并发和并行性通常用于多线程程序.但是,并发和并行性究竟是什么意思呢,它们是相同的术语还是什么? 简短的答案是“不”.它们不是相同的术语,尽管它们在表面上看起来非常相似.也花了我一些时间来终于找到并了解并发和并行性之间的区别.因此,我决定在这个Java并发教程中添加一个关于并发性与并行性的文本. 并发 并发意味着

固化型思维与成长型思维

最近读完一本书,<看见成长的自己>,这本书让我审视了自己长久以来所接受的思维观点,并给了我战胜心魔的力量,让我以后能专注把事情做更好,而不是因自己心里障碍做不了事.我把书里精彩的句子摘抄如下. 1. 在僵固思维模式里,这些品质代表的只是你手上的一把牌,而你总是试图说服自己和他人这是一把同花顺,却在内心深处担心这只是一对10.然而,在另外一种思维模式中,这把牌(不论是什么)仅仅是你走向成功的起点. 2. "不去冒险,就不会失败","如果你一开始没有成功,也许你就没有