leetcode刷题笔记

简单题

1.两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。你可以按任意顺序返回答案

个人答案:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int>v;
        for (int i = 0;i < nums.size(); i++)
        {
            for (int j =i+1;j < nums.size();j++)
            {
                if(nums[i]+nums[j]==target)
                {
                    
                    v.push_back(i);
                    v.push_back(j);
                    return v;
                }
            }
        }
        v.push_back(0);
        v.push_back(0);
    return v;
    }
};
vector<int> twoSum(vector<int>& nums, int target)
{
	vector<int>v;//用于存放返回数组的下标
    map<int, int> m;//key存放数值,value存放在数组中的位置
    for (int i = 0; i < nums.size(); i++)
	    {
       	 	if (m.count(target - nums[i]) > 0)  //判断成功说明map中已经有和为target的数
        {
            v.push_back(i);
            v.push_back(m[target - nums[i]]);
        }
        	m.insert(make_pair(nums[i], i));
    	}
    v.resize(2, 0);
    return v;
    }

可以使用哈希表改进
哈希表:用数组的下标表示数值,用下标对应元素的值表示是否出现或位置。这里用STL中的map容器实现。
count(key)成员函数,统计key的个数。
用哈希表实现,时间复杂度比较低。

2.有效的括号

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。

bool isValid(string s) 
{
    int n = s.size();
    if (n % 2 == 1) {   //括号成对出现
        return false;
    }

    unordered_map<char, char> pairs = {   //哈希表
        {')', '('},
        {']', '['},
        {'}', '{'}
    };
    stack<char> stk;
    for (char ch : s) {
        if (pairs.count(ch)) {
            if (stk.empty() || stk.top() != pairs[ch]) {
                return false;
            }
            stk.pop();
        }
        else {
            stk.push(ch);
        }
    }
    return stk.empty();
}

总结:右括号总是与最近的括号进行匹配,因此用栈比较方便,左括号入栈,右括号则与栈顶匹配,若为同种括号,则出栈,否则返回false,用哈希表进行匹配可以减少代码量,降低空间复杂度,最后若判断栈是否为空,若为空则全部匹配成功,返回true,否则返回false。

3.数组中重复的数字

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
个人答案:

    int findRepeatNumber(vector<int>& nums) {
        vector<int> v_hash;
        v_hash.resize(nums.size(),0);
        for (int i = 0;i < nums.size();i++)
        {
            if(v_hash[nums[i]] != 0)
            {
                return nums[i];
            }
            v_hash[nums[i]]++;
        }
        return 0;
    }

总结:利用哈希表可以比较容易完成

4.替换空格

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

个人答案:

string replaceSpace(string s) {
        while(true)
        {
            int pos = s.find(' ');
            if(pos == -1)
            {
                break;
            }
            s.replace(pos,1,"%20");
        }
        return s;
    }

总结:利用stl可以很方便的完成

5.从尾到头打印链表

输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
个人答案:

vector<int> reversePrint(ListNode* head) {
        ListNode *temp = head;
        stack<ListNode*> s;
        while(temp)
        {
            s.push(temp);
            temp = temp->next;
        }
        vector<int>v;
        while(!s.empty())
        {
            v.push_back(s.top()->val);
            s.pop();
        }
    return v;
    }

总结:从尾到头,正好对应栈的后进先出,故可以先将链表依次入栈,然后依次出栈,存入数组中。思路2,利用vector的insert函数,将没个结点插入到头部,v.begin()。思路3,递归

6.用两个栈实现队列

用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )

class CQueue {
public:
    stack<int> st1;
    stack<int> st2;
    CQueue() {
        
    }

    void appendTail(int value) {
        if (st1.empty()) {
            st1.push(value);
            return;
        }
        st2.push(value);
    }

    int deleteHead() {
        if (st1.empty()) {
            return -1;
        }
        int ret = st1.top();
        st1.pop();
        if (st1.empty()) {
            while (!st2.empty()) {
                st1.push(st2.top());
                st2.pop();
            }
        }
        return ret;
        
    }
};

总结: 思路为一个栈1只出栈(作为队列头部),栈2只入栈(作为队列尾部),当栈1为空时,将栈2的元素依次出栈存储到栈1中,便可以反转入栈顺序,实现先进先出。

7.斐波那契数列

//递归
class Solution {
public:
    int fib(int n) {
		return n < 2 ? n : fib(n - 1) + fib(n -2);
    }
};
//动态规划
class Solution {
public:
    int fib(int n) {
		for (int i = 0; i < n; i++)
		{
			int c = b;
			b = a + b;
			a = c;
		}
		return a;
    }
};

总结:最后返回a是因为多执行了一次循环,简化了单独判断n为0的情况,实际上a为斐波那契数列中的第n天的值,b是n+1天。

中等题

1.二维数组中的查找

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

示例:

[
  [1,   4,  7, 11, 15],
  [2,   5,  8, 12, 19],
  [3,   6,  9, 16, 22],
  [10, 13, 14, 17, 24],
  [18, 21, 23, 26, 30]
]

个人答案:

bool findNumberIn2DArray(vector<vector<int>>& matrix, int target) { //暴力查找
        for (int i = 0;i < matrix.size();i++)
        {
            for(int j = 0;j < matrix[i].size();j++)
            {
                if(matrix[i][j] > target)
                {
                    break;
                }
                if(matrix[i][j] == target)
                {
                    return true;
                }
            }
        }
        return false;
    }

总结:可以考虑优化思路,根据题目特性,可以从左下角开始查找,比target大则前往上一行查找,小则往右查找。


本文的所有题目以及除“个人答案”以外的代码均来自力扣(leetcode)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值