牛客网-面试必刷100题 上篇

*ps:*每天刷刷面试题目,新的感悟就通过写博客发出来了,就不需要用一些云笔记去整理了哈哈,希望大佬们不要介意~ 博客目录在右侧->

BM1 反转链表-递归

这应该是一个比较经典的链表例题,每个算法网站上都会有:下面给出递归的写法,当然有很多大佬也有别的方法去巧妙的解决,我会多多留意然后更新~
在这里插入图片描述在这里插入图片描述
C Version:

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */

/**
 * 
 * @param pHead ListNode类 
 * @return ListNode类
 */
struct ListNode* ReverseList(struct ListNode* pHead ) {
    if(pHead->next==NULL||pHead==NULL){
        return pHead;
    }
    struct ListNode* newpHead=ReverseList(pHead->next);
    pHead->next->next=pHead;//目的是2要放在3的后面
    pHead->next=NULL;//同时把2后面的指向弄成NULL
    return newpHead;
}

BM2 链表内指定区间反转

思路比较多,因为没有规定必须要修改节点,所以你可以直接去改对应节点的值,但是这的确是个馊主意,你也可以利用先进后出的栈来做…
-C语言版本
但是正常的话,还是给自己应该提升难度来做,通过修改节点之间的关系:
-C++版本
在这里插入图片描述
C version:

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param head ListNode类 
 * @param m int整型 
 * @param n int整型 
 * @return ListNode类
 */
struct ListNode* reverseBetween(struct ListNode* head, int m, int n ) {
    // write code here
    struct ListNode *p1,*p2;
    int num,clock=0,i=0;
    p1=p2=head;
    if(head==NULL||head->next==NULL){
        return head;
    }
    for(int i=1;i<m;i++){
        p1=p1->next;
    }
    p2=p1;
    for(int p=0;p<n-m;p++){
        p2=p2->next;
    }
        num=p1->val;
        p1->val=p2->val;
        p2->val=num;
    return head;
 
}

C++ version:

//1.将原链表分为三部分,m之前,m到n直接,n之后,并切断其联系
//2.将m,n之间链表反转
//3.将三部分重新连接
class Solution {
public:
    ListNode *reverseBetween(ListNode *head, int m, int n) {
        ListNode* dummy = new ListNode(-1);
    	dummy->next = head;
        ListNode* pNode = dummy;
    	ListNode* ftail = pNode,*rhead = NULL, *rtail = NULL, *res = NULL;
        for (int i = 0; i < m - 1; i++)
        	ftail = ftail->next;
        rhead = ftail->next;
        ftail->next = NULL;
        ListNode* prev = NULL, *pcur = rhead, *pnext = rhead->next;
        for (int i = m; i <= n;i++) {
            pcur->next = prev;
            prev = pcur;
            pcur = pnext;
            pnext = pnext->next;
        }
        res = pcur;
        ftail->next = prev;
        rhead->next = res;
        ListNode* phead = dummy->next;
        dummy->next = NULL;
        delete dummy;
    	return phead;
    }
};

BM3 链表中的节点每k个一组翻转

考虑用栈的特性来做,当时想用链式栈来做,这样出栈的适合就不用去建新的链表了,但是写了半天发现用C过不了…搬运了一下别的大佬的C++版本来学习一下把…栈使用的是顺序存储的结构,顺序压栈,然后出栈建新链表来完成的.具体可以看一下注释那里的链接哦~
在这里插入图片描述
C++ version:

/*
用栈的操作:入栈然后出栈,然后新建链表
https://www.nowcoder.com/practice/b49c3dc907814e9bbfa8437c251b028e?tpId=295&tqId=722&ru=/exam/oj&qru=/ta/format-top101/question-ranking&sourceUrl=%2Fexam%2Foj
*/

class Solution{
public:
    ListNode* reverseKGroup(ListNode* head, int k) {
        if(head==NULL)return head;
        ListNode* head2=new ListNode(0);//新建链表
        ListNode* p=head2;//p是头指针
        stack<int>s,s2;
        while(head){//遍历旧链表
            s.push(head->val);//权值压入栈
            if(s.size()==k){//当栈满k个元素,就将栈内元素全部出栈用以新建链表
                while(!s.empty()){
                    p->next=new ListNode(s.top());s.pop();//新建链表
                    p=p->next;//指针后移
                }
            }
            head=head->next;//指针后移
        }
        while(!s.empty()){//当栈s还有剩余,即链表结点不能被k整除时,将剩下的元素入两次栈,即可实现原顺序的结点权值 
            s2.push(s.top());s.pop();
        }      
        while(!s2.empty()){
            p->next=new ListNode(s2.top());s2.pop();//新建链表
            p=p->next;//指针后移
        }      
        return head2->next;//返回结果链表
    }
};

BM4 合并两个排序的链表

这个也比较经典,但是注意,新的链表也是要符合升序的排列,题目好像没有说的太清楚,只说明了给出的链表是升序的,其实最终的链表也需要升序,我第一次就中招了,没理解清楚:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

C Version:

struct ListNode* Merge(struct ListNode* pHead1, struct ListNode* pHead2 ) 
{
    struct ListNode* vhead = (struct ListNode*)malloc(sizeof(struct ListNode)); //新建一个头结点
    vhead->val = -1;
    struct ListNode *p = vhead;   //用一个指针指向该头结点
        while (pHead1 && pHead2)    //两个链表都未比较完
       {
            if (pHead1->val <= pHead2->val) //表1的值更小
           {
                p->next = pHead1;    //先将结点连接到新表,再让原表指针后移一位,二者顺序不可换
                pHead1 = pHead1->next;
            }
            else {
                p->next = pHead2;
                pHead2 = pHead2->next;
            }
            p = p->next;  //加入一个新结点后,新表指针也后移一位
        }
        p->next = pHead1 ? pHead1 : pHead2;  //都比较完后,哪个表非空则直接加入到新表中
        return vhead->next;  //返回第一个结点
    }


BM6 判断链表中是否有环 -快慢指针

今天的题目比较简单,但是对运行时间有点要求:
在这里插入图片描述
在这里插入图片描述

#include <stdbool.h>
/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */

/**
 * 
 * @param head ListNode类 
 * @return bool布尔型
 */
/*
bool hasCycle(struct ListNode* head ) {
    // write code here
    if(head==NULL||head->next==NULL){
        return false;
    }
    struct ListNode *p1=head->next;
    while(p1->next!=head->next){
        if(p1->next==NULL){
            return false;
        }
        p1=p1->next;
    }
    return true;
    //我的本意是直接去用一个指针去遍历,如果有循环圈圈的话,一定会p1->next==第二个节点的地址,但是这个方法好像超时了
}
*/
//这里我用参考大神的方法去写,这里我使用快慢指针的方法,慢指针每次都执行一次next,而快指针每次都执行两次的next,如果有循环的话,两个地址一定会遇见
bool hasCycle(struct ListNode* head ) {
    if(head==NULL||head->next==NULL){
        return false;
    }
     struct ListNode *slow = head, *fast = head;
        while (fast && fast->next) {
            slow = slow->next;
            fast = fast->next->next;
            if (slow == fast) return true;
        }
        return false;
    
}

BM7 链表中环的入口结点

解法一:
这个题目看起来就是BM6的升级版,需要我们进一步的去确定交点的位置:那么我首先想到的就是哈希表的原理,把链表的值存储到哈希表中,然后遍历的过程中,如果有重复的节点地址,那么改地址就是我们要得到的节点的位置:
用C实现哈希表比较繁琐,C++的STL给我们分享了一个unordered_set
关于这个unordered_set:它的特点简单的说是能够天然去重,里面存储的值是不相同的,所以我们用来存储地址是不错的选择,而且合理的用好它的find()和end方法

成员方法功能
find (key)查找值为key的元素,如果找到,则返回一个指向该元素的正向迭代器;如果没找到,则返回一个与end()方法相同的迭代器
end返回指向容器中最后一个元素之后位置的迭代器

具体的功能和例子可以参考这个链接:unordered_set中end()与find()的使用
解法二: 参考的大神的解法,我是没想到这一层,实际上看成一个数学问题:
快慢指针思想:
初始化:快指针fast指向头结点, 慢指针slow指向头结点
让fast一次走两步, slow一次走一步,第一次相遇在C处,停止
然后让fast指向头结点,slow原地不动,让后fast,slow每次走一步,当再次相遇,就是入口结点。

在这里插入图片描述
在这里插入图片描述
C++ version:

class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead) {
        unordered_set<ListNode *> ret;//这个容器容纳的是节点的地址
        ListNode *p;
        p=pHead;
        while(p){
            if(ret.find(p)==ret.end()){//find方法,如果能从容器当中找不到与p相同的地址,则find与end相同
                ret.insert(p);
                p=p->next;
            }
            else{
                return p;
            }
        }
        return NULL;
        
    }
};

附解法二:

class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        ListNode *fast = pHead;
        ListNode *slow = pHead;
        while (fast &amp;&amp; fast-&gt;next) {
            fast = fast-&gt;next-&gt;next;
            slow = slow-&gt;next;
            if (fast == slow) break;
        }
        if (!fast || !fast-&gt;next) return nullptr;
        fast = pHead;
        while (fast != slow) {
            fast = fast-&gt;next;
            slow = slow-&gt;next;
        }
        return fast;
    }
};

BM8 链表中倒数最后k个结点

1.头插法:
先用vector获取一下ListNode* 的所有节点,然后对vector反转一下,最后从下标0遍历到k结束,期间使用头插法来构建链表,就可以得到倒数最后k个节点
2.双指针:
双指针,定于两个指针fast和slow,让fast先跑k步,然后slow和fast同时开始跑,当fast为null时,slow的值就是第k个节点,输出slow即可。这个过程画个图就很清晰明了了。

这一过程大多数人都会做,主要是边界条件不要忘了判断。

<1>当链表为空时,当k <= 0时,都要输出为空
<2>当链表长度小于k时,输出为空。如果k大于链表长度,根据前面写好的程序可以得知,此时的fast已经为null了,而i却还小于k,所以直接在最后面加个判断语句就行了。
在这里插入图片描述
在这里插入图片描述

C++:
头插法:

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 *	ListNode(int x) : val(x), next(nullptr) {}
 * };
 */
class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pHead ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    ListNode* FindKthToTail(ListNode* pHead, int k) {
        // write code here
        vector<ListNode *> ret_int;
                    ListNode * p;
        if(!pHead||k==0){
            return NULL;
        }
        while(pHead){
            ret_int.push_back(pHead);
            pHead=pHead->next;
        }
        if(ret_int.size()<k){
            return NULL;
        }
        else{
            reverse(ret_int.begin(), ret_int.end());
            p=ret_int[0];
            for(int i=1;i<k;i++){
                ListNode *p1=(ListNode *)malloc(sizeof(ListNode));
                p1=ret_int[i];
                p1->next=p;//头插法
                p=p1;
            }
            
        }
        return p;
    }
};

双指针:

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param pHead ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    ListNode* FindKthToTail(ListNode* pHead, int k) {
        if(nullptr == pHead || k <= 0)
            return nullptr;
        ListNode *p = pHead, *q = pHead;
        while(nullptr != p && k)
        {
            --k;
            p = p->next;
        }
        if(k)
            return nullptr;
        while(p)
        {
            p = p->next;
            q = q->next;
        }
        return q;
    }
};

BM9 删除链表的倒数第n个节点

本题是要删除倒数的第n个节点:
1.可以参考之前的方式,把节点存入vector数组当中,然后反转一下,然后删除第n个节点,最后使用头插法进行构建新链表返回即可;
2.使用快慢指针的方式,快指针和慢指针之间要相差n个节点,当快指针到了节点末尾的时候,慢指针会正好处于第n-1个节点的位置上,这个时候要有两种情况:
如果n=1,意思是删除最后一个节点,那么直接给慢指针->next=NULL
如果n>1,那么就慢指针->next=慢指针->next->next;意思是越过第n个节点,直接把第n+1个节点交给慢指针的next;
在这里插入图片描述
C++ version:快慢指针

/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param head ListNode类 
     * @param n int整型 
     * @return ListNode类
     */
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        // write code here
        vector<ListNode *>res_vec;
        ListNode *p1=head;
        ListNode *p2=head;
        int num=0;
        if(n==2){
            return head->next;
        }
        if(!head){
            return NULL;
        }
        for(int i=0;i<n-1;i++){
            p1=p1->next;
        }
        while(p1){
            p2=p2->next;
            p1=p1->next;
        }
        p2->next=p1;
        return head;
        
        
    }
};

BM17 二分查找-I

二分查找:记住while条件
在这里插入图片描述

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型vector 
     * @param target int整型 
     * @return int整型
     */
    int search(vector<int>& nums, int target) {
        // write code here
        
        vector<int>::iterator it = find(nums.begin(),nums.end(),target);;
        if(it !=nums.end()){
            return it-nums.begin();
        }
        else
        return -1;
    }
};

BM18 二维数组中的查找

考察的其实就是二分法,把每一列都看作一个有序的数列,使用二分法进行判断target是否在里面;
如果不在,就换第i列继续二分查找:
注意每次进入新的一列的二分查找的时候,要将left=0,right=size-1;
二分查找的过程中,一般会出现两种情况:
1.要么就是mid,找到了和target的值,此时只需要return 返回即可;
2.要么就是没有找到target的值,并且left>right;

class Solution {
public:
    bool Find(int target, vector<vector<int> > array) {
        int left;
        int right;
        int mid;
        if(!array.size())
            return false;
        
        if(!array[0].size())
            return false;
        for(int i=0;i<array.size();i++){
            left=0;
            right=array.size()-1;
            while(left<=right){
                    mid=(left+right)/2;
                if(target==array[i][mid]){
                    return true;
                }
                if(target>array[i][mid])
                    left=mid+1;
                else
                    right=mid-1;
                
            }

           
        }
        return false;
    }
};

BM21 二叉树的前序遍历#c/c++递归的写法

在这里插入图片描述
C Version:
递归先序遍历二叉树

BM24 二叉树的中序遍历

在这里插入图片描述

/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param root TreeNode类 
 * @return int整型一维数组
 * @return int* returnSize 返回数组行数
 */
//中序遍历:顺序左->根->右
static num;
void inorder(struct TreeNode *root,int *ret){
    if(!root){
        return ;
        
    }
    inorder(root->left, ret);
    ret[num++]=root->val;
    inorder(root->right, ret);
    
}
int* inorderTraversal(struct TreeNode* root, int* returnSize ) {
    // write code here
    if(!root){
        return NULL;
    }
    int *ret=(int *)malloc(sizeof(int)*10000);
    inorder(root, ret);
    *returnSize=num;
    return ret;
    
}

BM25 二叉树的后序遍历

在这里插入图片描述

/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param root TreeNode类 
 * @return int整型一维数组
 * @return int* returnSize 返回数组行数
 */
static num;
//后续遍历的顺序:left->right->mid
void postorder(struct TreeNode *root,int *ret){
    if(!root){
        return ;
        
    }
    postorder(root->left, ret);//left
    postorder(root->right, ret);//right
    ret[num++]=root->val;//mid
    
}
int* postorderTraversal(struct TreeNode* root, int* returnSize ) {
    // write code here
    int *ret=(int *)malloc(sizeof(int)*1000);
    postorder(root, ret);
    *returnSize=num;
    return ret;
    
}

BM26 求二叉树的层序遍历

前面三个属于深度遍历,一般采用递归比较方便理解;
层次遍历的话,一般采用的是使用队列的方法,因为层次遍历的思路:在这里插入图片描述
至于为什么要用队列的方式来实现,这里有个大神的博客可以参考一下:
树的层次遍历以及使用队列遍历过程图

这里涉及到STL的使用方法:queue 队列 vector容器,他们都有对应的方法实现进队出队和赋值:
一些我在注释当中标明:

C++ version:

/**
 * struct TreeNode {
 *	int val;
 *	struct TreeNode *left;
 *	struct TreeNode *right;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param root TreeNode类 
     * @return int整型vector<vector<>>
     */
    vector<vector<int> > levelOrder(TreeNode* root) {
        // write code here
        int size;
        vector<vector<int>>ret;//相当于C语言的二维数组
        if(!root){
            return ret;
        }
        queue<TreeNode *>ret_queue;//STL的队列声明
        vector<int> ret_int;//声明一维数组
        ret_queue.push(root);//根节点进队列
        while(!ret_queue.empty()){
        //empty():如果 queue 中没有元素的话,返回 true。
            size=ret_queue.size();
            ret_int.clear();//记得把数组的元素清0,不然的话上一个根节点会进入到第二行当中
            while(size--){//size监视队列的长度
                
                TreeNode *num=ret_queue.front();
                ret_queue.pop();//出队列
                ret_int.push_back(num->val);//把根节点的值拿过来存入数组当中
                if(num->left) ret_queue.push(num->left);
                if(num->right) ret_queue.push(num->right);

            }
            if(ret_int.size()>0) ret.push_back(ret_int);//添加每行的一维数组

        }
        return ret;
        
    }
};

BM27 按之字形顺序打印二叉树

可以理解为BM26的进阶版本,无疑就是之前按照层次遍历的顺序,现在要求是奇数层次层次遍历自左向右,偶数层次要求自右向左,这个问题并不难:
1.你可以设置一个变量,代表层数,参照上面BM26的模板。当层数为偶数的时候,你可以先让根节点的右子树进队列再根节点的左子树进队列;
2.参考BM26的模板,当层数为偶数的时候,你可以去将一维数组,反转一下,这样就是自右向左啦,期间用到的函数是vector的reverse:
关于Vector的详细用法:参考博客哦:
Vector的使用方法:
在这里插入图片描述
在这里插入图片描述
C++ Version:

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};
*/
class Solution {
public:
    vector<vector<int> > Print(TreeNode* pRoot) {

        int num,res=0;
        vector<vector<int>> ret_Twoint;
                if(!pRoot){
            return ret_Twoint ;
        }
        vector<int> ret_int;
        queue<TreeNode *>ret_queue;
        TreeNode * p;
        ret_queue.push(pRoot);//队列存储根节点
        while(!ret_queue.empty()){
                num=ret_queue.size();//获取队列长度
                ret_int.clear();//每次清除掉前面的size
                res++;
            while(num--){
                    p=ret_queue.front();//获取第一个元素
                    ret_queue.pop();//出队列
                    ret_int.push_back(p->val);
                          if(p->left){
                        ret_queue.push(p->left);
                    }
                    if(p->right){
                        ret_queue.push(p->right);
                    }
            }
             
             if(ret_int.size()){
                 if(res%2==0){
                     reverse(ret_int.begin(), ret_int.end());//反转一下数组
                 }
                 ret_Twoint.push_back(ret_int);
                 
             }

        }
        
        return ret_Twoint;
    }
};

NC37 合并区间

首选需要对区间进行一个排序,排序的规则是按照区间的start的高低来排序:
这里需要重写一个sort排序,来实现vector的排序;
在这里插入图片描述
c++ version:

/**
 * Definition for an interval.
 * struct Interval {
 *     int start;
 *     int end;
 *     Interval() : start(0), end(0) {}
 *     Interval(int s, int e) : start(s), end(e) {}
 * };
 */
class Solution {
public:
     static bool cmp_1(const Interval &a,const Interval &b) { //重载比较
         if(a.start < b.start)
             return true;
         else
             return false;
    }
    
    vector<Interval> merge(vector<Interval> &intervals) {
        vector<Interval> res;
        if(intervals.size() == 0) //去除特殊情况
            return res;
        sort(intervals.begin(), intervals.end(),cmp_1); //按照区间首排序
        res.push_back(intervals[0]); //放入第一个区间
        for(int i = 1; i < intervals.size(); i++){ //遍历后续区间,查看是否与末尾有重叠
            if(intervals[i].start <= res.back().end) //区间有重叠,更新结尾
                res.back().end = max(res.back().end, intervals[i].end);
            else //区间没有重叠,直接加入
                res.push_back(intervals[i]);
        }
        return res;
    }
};

BM42 用两个栈实现队列

题目比较简单,栈的特点是先进后出,队列的特点是先进先出,队列的实现,只需要将stack1压栈,然后再出栈给stack2,最后把stack2出栈,达到了负负得正的效果,从而就得到了队列的先进先出的效果:
注意考虑,当push1 push2 pop push3 pop pop的时候:
请添加图片描述
在这里插入图片描述

C++ version:

class Solution
{
public:
    void push(int node) {
        vector<int> ret;
         stack1.push(node);//进栈
        
    }

    int pop() {
                int num_2,num_3;
        if(!stack2.empty()){
            num_3=stack2.top();
            stack2.pop();
            return num_3;
        }
        while(!stack1.empty()){
            int num=stack1.top();
            stack1.pop();
            stack2.push(num);
        }

        num_2=stack2.top();
        stack2.pop();
        return num_2;
        
    }

private:
    stack<int> stack1;
    stack<int> stack2;
};

BM43 包含min函数的栈

功能就是在出栈入栈的基础上,添加一个能返回min最小值的功能:
可以在每次入栈的时候,二次重复压栈,每次栈顶元素是最小值:
例如入栈-1 2 然后取min:
请添加图片描述

C++ version:

class Solution {
public:
    public:
    void push(int value) {
        int ret_push;
        if(stack_1.empty()){
            stack_1.push(value);//栈中无元素就只进一个
            stack_1.push(value);
        }
        else{
            ret_push=stack_1.top();//出栈一个元素
            stack_1.push(value);
            if(ret_push<value){
                stack_1.push(ret_push);//永远把小的放在栈顶
            }
            else{
                stack_1.push(value);//永远把小的放在栈顶
            }
        }

    }
    
    void pop() {
        stack_1.pop();
        stack_1.pop();
    }
    int top() {//注意获取top的时候,获取完毕一次,记得把上面的最小值在还回来。
        int num,num_2;
        if(stack_1.empty()){
            return 0;
        }
        num_2=min();
        stack_1.pop();
        num=stack_1.top();
        stack_1.push(num_2);
        return num;
    }
    int min() {
        int num;
        if(stack_1.empty()){
            return 0;
        }
        num=stack_1.top();
        //二次获取的时候:
        return num;
        
        
    }
    private:
        stack<int> stack_1;
};

BM50 两数之和

1.暴力求解:直接两个for循环遍历,然后找一下有没有和是target的情况;
2.使用哈希表,用Target-number[i] ,然后搜查一下Target-number[i] 在number中有没有,有的话就返回下标res。注意判断排除一下下标是否和i相同的情况。
在这里插入图片描述
C++ version:
哈希表:

 class Solution {
public:
    /**
     * 
     * @param numbers int整型vector 
     * @param target int整型 
     * @return int整型vector
     */
    vector<int> twoSum(vector<int>& numbers, int target) {
        vector<int>res;//保存结果
        map<int,int>mp;//定义一个哈希表存储numbers[i]和对应的下标
        for (int i = 0; i < numbers.size(); i ++) {//进行标记
            mp[numbers[i]] = i;
        }
         for (int i = 0; i < numbers.size(); i++) {
             //每遍历一个numbers[i]就去对应的mp里找有没有target - numbers[i]
             //如果有就返回结果
             //如果没有就找下一个
            if(mp.find(target - numbers[i]) != mp.end() && i != mp[target - numbers[i]]){
                res.push_back(i + 1);
                res.push_back(mp[target - numbers[i]] + 1);
                return res;
            }
        }
        return res;


    }
};

本博客使用到的友情链接:

Vector的使用方法:
Stack的使用方法
Queue的使用方法
树的层次遍历以及使用队列遍历过程图
unordered_set中end()与find()的使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

嵙嵙程序猿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值