精华内容
下载资源
问答
  • 题目是:一个二维矩阵,给一个数,判断这个数存不存在于这个矩阵当中,当然,这个矩阵也是一个有规律矩阵。即从上往下,从左往后都是递增。 最普通就是从上到下,从左到右一个一个的进行判断寻找。这时,在最...

    题目是:一个二维矩阵,给一个数,判断这个数存不存在于这个矩阵当中,当然,这个矩阵也是一个有规律的矩阵。即从上往下,从左往后都是递增的。

    最普通的就是从上到下,从左到右一个一个的进行判断寻找。这时,在最坏情况下,就得将整个矩阵轮训一遍。那么时间复杂度就为O(N),那么可不可以减少呢?就要从这个矩阵的特殊地方开始了。

    因为这个矩阵是从上到下,从左到右递增的,那么我们可以首先将第一行最后一列的元素和要判断的数进行比较,如果大了,那么就可以将最后一列删掉,如果小了就将第一行删掉 ,以为这个数是第一行最大的,第一列最小的。接下来递归调用该矩阵。直到找到该数,或者没有该数存在。看代码

    #include <iostream>
    
    using namespace std;
    
    bool isExist(int num[],int row,int field,int key)
    {
        int i = 0;
        int j = field;
        while(i < row && j >= 0)
        {
            if (key == num[i*field+j])
            {
                return true;
            }
            if (key < num[i*field+j])
            {   
                j--;
            }   
            if (key > num[i*field+j])
            {   
                i++;
            }   
        }   
    
        return false;
    }
    
    
    
    int main()
    {
        int num[3][3] = {1,2,3,4,5,6,7,8,9};
        bool result = isExist((int*)num,3,3,5);//将其转换为一位数组,比较灵活一些
        if (result)
            cout<<"yes"<<endl;
        else
            cout<<"no"<<endl;
    
        return 0;
    }

    这个算法的时间复杂度是低于O(N)的。

    展开全文
  •  我考虑DFS参数有3个,第一个是当前位置,还有一个是余剩步数(我想到最多只能够走K次),还有一个是此次搜索起点。  剪枝:跳过度为1点,因为度为1点不可能处于环上  我自己也认识到,这

          题目的大概意思就是在给出的图里面寻找一个长度为K的环。。。

          想了一想,肯定是用DFS,然后就考虑实现,可是以什么作为参数呢,以下是我考虑不恰当的地方:

          我考虑的DFS参数有3个,第一个是当前的位置,还有一个是余剩的步数(我想到最多只能够走K次),还有一个是此次搜索的起点。

          剪枝:跳过度为1的点,因为度为1的点不可能处于环上

          我自己也认识到,这样的搜索有很大的重复性,比方说我从一个节点A向下寻找,在K步之内没有找到,接下来我会去在A+1处调用DFS,假若A和A+1相邻,此时所做的很大一部分工作是重复的,因为从A向A+1这边搜索的时候,已经搜索过一部分了,现在再搜索也仅仅是比原来多走一步而已。我想把走过的步数记录下来,可是没有想到好的办法,结果TLE到比赛结束。

      比赛完之后去看题解发现自己没法实现的东西轻易的就可以实现。。。不得不说有点遗憾?

      这个DFS里面有三个参数,第一个是当前的节点,第二个是离源节点的步数,第三个是父节点(也就是从哪边过来的)

      在DFS搜索里面用来表示是否访问过的VIS数组来表示这个是离调用点有多少步,访问到某一个点P时,假若P已经访问过了,那么就把VIS里保存的步数取出来和当前的步数相比较,假若是K的话,那么就表明经过了一个环了。假若不是K,那么继续调用DFS。

      这样的好处是一次可以搜索完一个连通子图,而不用像我之前那样对每一个节点都调用,显然要少做很多的重复性工作。以下是AC的代码,同样有跳过度为1的点的剪枝

    #include <cstdio>
    #include <cstring>
    #include <vector>
    
    using namespace std;
    
    vector<int> v[55];
    int vis[55],n,m,x,y,t,k;
    bool flag,_find(int now,int pos,int pre);
    
    int main(){
        scanf("%d",&t);
        while(t--){
            scanf("%d%d%d",&n,&m,&k);
            for(int i=0;i<m;++i)
                scanf("%d%d",&x,&y),v[x].push_back(y),v[y].push_back(x);
    
            for(int i=0;i<n;++i)
            if(v[i].size()>1&&_find(i,1,-1))
            flag=true,i=n;
    
            printf("%s\n",(flag)?"YES":"NO");
            flag=false;memset(vis,0,sizeof(int)*n);
            for(int i=0;i<n;++i)
                v[i].clear();
        }
        return 0;
    }
    
    bool _find(int now,int pos,int pre){
        if(vis[now])
            return pos-vis[now]==k;
        vis[now]=pos;
        for(int i=0;i<v[now].size();++i)
        if(v[now][i]!=pre&&v[v[now][i]].size()>1&&_find(v[now][i],pos+1,now))
            return true;
        return false;
    }
    


      为了做比较,我把之前的TLE的代码也贴出来


    #include<cstdio>
    #include<vector>
    #include<cstring>
    
    using namespace std;
    
    int t,n,m,k,x,y;
    
    vector<int> v[55];
    bool _find(int pos,int remain,int recourse),flag=false;
    int visi[55];
    
    int main(){
        scanf("%d",&t);
        while(t--){
            scanf("%d%d%d",&n,&m,&k);
            for(int i=0;i<m;++i)
                scanf("%d%d",&x,&y),v[x].push_back(y),v[y].push_back(x);
            //printf("%d\n",v[0].size());
            for(int i=0;i<n;++i)
            if(v[i].size()>1&&_find(i,k,i)){
                    flag=true;
                    break;
            }
            printf("%s\n",(flag)?"YES":"NO");
            for(int i=0;i<n;++i)
                v[i].clear();
            flag=false;memset(visi,0,sizeof(visi));
        }
        return 0;
    }
    
    bool _find(int pos,int remain,int recourse){
        if(remain<=0)
            return false;
        visi[pos]=1;
            for(int i=0;i<v[pos].size();++i){
                if(visi[v[pos][i]]==1&&v[pos][i]==recourse&&remain==1)
                    return true;
                else if(v[v[pos][i]].size()>1&&visi[v[pos][i]]==0){
                    if(_find(v[pos][i],remain-1,recourse))
                        return true;
                }
            }
        visi[pos]=0;
        return false;
    }

      这样写完之后,感觉自己的想法也清晰了很多。。


           补充:虽然我说的第一种解法很好,可是第一种解法是仅仅针对于部分的情况,由于CSUOJ的数据的问题,导致有一些情况无法正常的判断出来,比如说http://blog.csdn.net/nameofcsdn/article/details/52184252 这儿的给出的一个数据反例,经测试我说的AC代码是无法正常运行出正确的结果,可是用我原来的搜索代码就可以得到正确的答案,看来我考虑问题还是应该要深入一些才好。


    展开全文
  • 输入两个链表,找出它们的第一个公共结点。 思路 我的第一想法是,一个链表的结尾连着第二链表的开头,如果有公共结点,就形成了一个环,问题就变成了寻找环的入口节点。然后就超时了。 后来看了答案,感觉自己真实...

    题目

    输入两个链表,找出它们的第一个公共结点。

    思路

    • 我的第一想法是,一个链表的结尾连着第二链表的开头,如果有公共结点,就形成了一个环,问题就变成了寻找环的入口节点。然后就超时了。
    • 后来看了答案,感觉自己真实想多了,有两种方法。
    • 第一种方法利用栈。
      • 如果两个链表有公共部分,要找到入口结点的话,可以从链表的尾部向前数,直到第一个相同的地方。但是链表不能倒着遍历,所以可以使用两个栈,将两个链表的结点依次入栈,最后通关判断栈顶元素来找到第一个公共结点。
    • 第二种方法不使用辅助空间。
      • 先计算两个链表的长度,然后让指向较长链表的指针先走几步,达到的位置到结尾的长度与另一个链表的长度一样,然后两个链表同时遍历,找到第一个相同的结点。

    栈方法代码

    /*
    struct ListNode {
        int val;
        struct ListNode *next;
        ListNode(int x) :
                val(x), next(NULL) {
        }
    };*/
    class Solution {
    public:
        ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
            stack<ListNode*> s1, s2;
             
            ListNode* p1 = pHead1;
            while ( p1 ) {
                s1.push( p1 );
                p1 = p1->next;
            }
             
            ListNode* p2 = pHead2;
            while ( p2 ) {
                s2.push( p2 );
                p2 = p2->next;
            }
             
            ListNode* node = nullptr;
            while ( !s1.empty() && !s2.empty() && s1.top() == s2.top() ) {
                node = s2.top();
                s1.pop();
                s2.pop();
            }
             
            return node;
        }
    };
    

    不用栈的代码

    /*
    struct ListNode {
    	int val;
    	struct ListNode *next;
    	ListNode(int x) :
    			val(x), next(NULL) {
    	}
    };*/
    class Solution {
    public:
        ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
            if ( !pHead1 || !pHead2 ) return nullptr;
          
            ListNode *p1 = pHead1, *p2 = pHead2;
            
            // 得到两个链表的长度。
            int length1 = getListLength( pHead1 );
            int length2 = getListLength( pHead2 );
            
            // 让长的链表作为第一个链表
            if ( length2 > length1 ) {
                p1 = pHead2;
                p2 = pHead1;
                
                int temp = length1;
                length1 = length2;
                length2 = temp;
            }
            
            // 指向长链表的指针先走,使得两个链表剩下的结点数相同。
            while ( length1 != length2 ) {
                --length1;
                p1 = p1->next;
            }
            
            // 寻找第一个公共结点
            ListNode* node = nullptr;
            while ( p1 ) {
                if ( p1 == p2 ) {
                    node = p1;
                    break;
                }
                
                p1 = p1->next;
                p2 = p2->next;
            }
            
            return node;
        }
        
        int getListLength( ListNode* p ) {
            /*计算链表的长度*/
            int length = 0;
            while ( p ) {
                ++length;
                p = p->next;
            }
            
            return length;
        }
    };
    
    展开全文
  • 今天去了某个搞量化投资公司面试实习生,坐了一个多小时地铁终于找到了地方,唉,上海今天空气质量又 爆表了,懒得吐槽了。到地点后,直接给了一张纸,有一道题,10分钟作答。  题目大概是这样:在“abc ...

        今天去了某个搞量化投资的公司面试实习生,坐了一个多小时的地铁终于找到了地方,唉,上海今天的空气质量又 爆表了,懒得吐槽了。到地点后,直接给了一张纸,有一道题,10分钟作答。

        题目大概是这样的:在“abc abf abc str jslt str abf 7788 7788 fasd fkjl unnid ...”中找到第四个出现两次或者两次以上的字符串。当时一看就慌了,主要是好久没有手写代码了,一开始以为要完整的写出程序,而我恰好关于文件录入的函数记不大清了(后来证明只要写伪代码就好了),时间又比较紧,只好飞快的搜索大脑,绞尽脑汁,想出了一个方案,思路虽然是对的,当时解答也没什么问题,但是回来之后想了想,还是有许多小细节错误,所以就在机器上又完整的写了一遍,跑了一下,代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <map>
    
    using namespace std;
    
    struct charnum {
            char str[10];
            int num;
    };
    
    int main()
    {
            FILE *fp = fopen("data.txt", "rw+");
            char tmp[10] = {0};
            struct charnum tmpstr;
            map<int, struct charnum> mystr;
            int num = 0;
            int cou = 0;
            bool found = false;
            while (fscanf(fp, "%s", tmp) != EOF && !found) {
                    map<int, struct charnum>::iterator it;
                    for (it = mystr.begin(); it != mystr.end(); it++) {
                            if (strcmp(it->second.str, tmp) == 0) {
                                    it->second.num++;
                                    if (it->second.num == 2) {
                                           cou++;
                                           if (cou == 4) {
                                                    printf("The 4th str: %s", tmp);
                                                    found = true;
                                                    break;
                                           }
                                    }
                            }
                    }
                    if (it == mystr.end()) {
                            memcpy(tmpstr.str, tmp, sizeof(tmp));
                            tmpstr.num = 1;
                            printf("%s\n", tmp);
                            mystr[num++] = tmpstr;
                    }
            }
            fclose(fp);
    }
    data.txt中的数据就是abc abf abc str jslt str abf 7788 7788 fasd fkjl unnid 。

    展开全文
  • 查找数第一反应是二分,而且该数组递减有序,不同的地方是左移了n位。 如果使用二分的话,得到的两部分将会是这样:一部分递减有序,一部分非有序。 对有序部分可二分查找,对非有序部分,他是该题目的子问题,...
  • 给定一个矩阵,x 为坐标起点,即可以用作出发的地方,T 为终点, 即要到达的地方,那么请给出 从 X 出发能到达 T 最短路径长度, 以及起点 X 坐标。 输入:矩阵地图 5 6 X00100 00000X 01T000 0X1010 00000X ...
  • 二进制寻找毒酒

    2020-10-28 23:00:27
    写在前面:在做一道算法分析题目的时候,遇到一个经典题目,也是一个很有技巧性的题目,在众多大佬的帮助解读下,以及交作业的厚积薄发下,结合经典“小白鼠试毒”(大学计算机书第一页)的讲解,其实对于这个这个题...
  • 遍历该数组,找到第一个前一个大于后一个数,否则返回最后一个数。时间复杂度O(n)。 解法2: 使用二分查找,时间复杂度O(lgn)。需要注意是二分的地方不能使用mid+1,否则会错过那个结点。 #in
  • 然后设置两个指针从链表开始,第一个节点先走k步,然后第二个指针指到链表开始,两个指针每次都向后走一步,两个指针相遇位置就是链表入口。 # -*- coding:utf-8 -*- class ListNode: def __init__(sel
  • 他建立了强大而富有国家,聚集了大批黄金象牙和钻石,并把这些价值连城珍宝藏在一个神秘的地方,这就是世人瞩目“所罗门王宝藏”。多少个世纪以来,人们一直在寻找这批早已失落古代文明宝藏,寻找盛产...
  • 从小到大</li><li>选择第一个活动,因为他就是最早结束活动</li><li>接着往后找最早结束活动,同时要满足该活动开始时间要大于等于上一个选择活动结束时间,一直到没有活动可以选择...
  • 洛谷链接 题目类型:递归水题 事实证明:四题位置只是个障眼法 思路细讲: (1)读入数据 注意用scanf,要不然10^6大数据完全会爆。 ...这个地方是本题难点。 很多人递归方式是这样(...
  • 考研数学作为标准化考试,其命题范围有明确的规定,我的第一轮复习主要就是依据考试大纲,详细了解考试的基本要求,题型、类别和难度特点,准确定位。对于考试大纲未作要求的内容和知识点,我都没有看。因为从历年...
  • 一张正方形方格纸,只能从左往右,从上往下折叠,折叠t次后有q次询问,每次询问给出是最终状态下方格坐标(左下角为(0,0)),代表在这个地方扎个洞,问你把方格纸展开后有多少个洞。每次询问是独立 ...
  • 确认了没有禁止对面试进行描述,没有禁止对面试题目的提及(自然我也不会精确详尽的说明每个问题,重点在于寻找可能错误的地方)之后,打算趁现在用沉重的心情做一个总结,毕竟即便失败了,大公司的面试经验也是一次...
  • 最初做法:将M条记录存下,然后从S人开始条遍历,设当前是i条转发,当(i - S)%N == 0时则视为中奖用户,检查是否获奖过,没获奖过则加入获奖名单并标记已获奖,若获奖过则向下寻找一位没获奖过用户;...
  • 答案是7这问题可以这么来解释,二维数组是维存,并且都是通过索引去寻找这些数,所以可以通过这种方式来寻找这些数按道理来说是不会出现a[0][2]这种数,但是这里却出现了,并且没有报错,这是因为越界...
  • 1010 Radix (25分)测试点1

    2020-06-02 13:52:16
    首先很容易想到,我寻找答案范围在一个确定范围内,而这个范围最小值是 第一个数字中最小数字+1,因为进制不可能小于某个数字,不然就是不合法。 那么最大数字呢?首先很容易想到是 第一个数字值val,...
  • 31. Next Permutation

    2018-11-11 12:13:49
    将相邻数左数与右边的第一个大于它的数替换 reverse右边的数列 这里有个有意思的地方,使用for(exp){if(exp)…}`的计算速度远低于使用while(exp &amp;amp; exp)的方式 代码: class Solution { public: //...
  •  翻译工作并非阐述自己的思想,翻译的第一要务是忠实地传达原著者的思想。虽然无法自由地表达自己的想法,然而,翻译的快乐就在于:使另一个人的好想法能让更多的人了解。当然,由于时间紧张,译者水平有限,错误...
  • CruiseYoung提供的带有详细书签的电子书籍目录 ... 该资料是《SQL Server 2008... 翻译工作并非阐述自己的思想,翻译的第一要务是忠实地传达原著者的思想。虽然无法自由地表达自己的想法,然而,翻译的快乐就在于:使...
  • 难度:简单 一、题目描述: 二、解题分析: 这道题要注意的地方是,每种输入只会存在一个答案,存在多种解的输入是不...第二种是从读取的第一个数的位置,先向前,后向后或者先向后,后向前遍历。这种方法会比...
  • 从左开始寻找,找到的第一个偶数,下标为s 从s+1开始往右找,找到第一个奇数,下标为e (意味着从下标s到下标e-1全都是偶数) 将s到e-1的元素都右移一位,然后将那个奇数放到下标为s的地方 依次类...
  • 面试题37:两个链表的第一个公共结点:首先依次遍历两个链表,记录两个链表的长度m和n,如果 m > n,那么我们就先让长度为m的链表走m-n个结点,然后两个链表同时遍历,当遍历到相同的结点的时候停止即可。对于 m ...
  • 棋盘问题,dfs+回溯

    2020-07-17 19:39:39
    点击题目 大致题意: 在一个矩阵里面,有个不规则的棋盘,#...dfs(int r,int num) // r代表在第r行找一列出来,num代表这是放的第num个棋子 当 num 等于k ,结果加1 for(寻找没有被访问过的某一列) { 继续递归寻找下一行的
  • 我一直WA原因应该是直接遍历结果字符串寻找第一个与原字符串第一个字符匹配的地方然后取余,发现有相同字符时候就不行,还有前导0迷惑了我想太多了。 #include<stdio.h> #include<std

空空如也

空空如也

1 2 3
收藏数 45
精华内容 18
关键字:

寻找题目的第一个地方是