Leetcode Hot 100
1.两数之和
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案
class Solution {
public:
vector<int> twoSum(vector<int>& nums, int target) {
vector<int> result;
unordered_map<int,int> mp;
for (int i =0; i<nums.size();i++)
{
if (mp.find(target-nums[i])!=mp.end())
{
result = {i, mp[target-nums[i]]};
return result;
}
mp[nums[i]] = i;//key:nums中元素 value:下标
}
return result;
}
};
相比于暴力解法,以空间换时间
时间复杂度O(n)
空间复杂度O(n)
2.两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
class Solution {
public:
ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
ListNode* dummyhead = new ListNode(0);
ListNode* cur = dummyhead;
int bitValue = 0;//每位的数字
int carry = 0;//进位
while(l1 || l2)
{
if (!l1)
{
bitValue = l2->val+carry;
l2 = l2->next;
}
else if (!l2)
{
bitValue = l1->val+carry;
l1 = l1->next;
}
else
{
bitValue = l1->val+l2->val+carry;
l1 = l1->next;
l2 = l2->next;
}
carry = bitValue/10;
ListNode* newNode = new ListNode(bitValue%10);
cur->next = newNode;
cur = cur->next;
}
if (carry)
{
ListNode* newNode = new ListNode(carry);
cur->next = newNode;
cur = cur->next;
}
return dummyhead->next;
}
};
时间复杂度O(max(m, n))
空间复杂度O(1)
3.无重复字符的最长字串
给定一个字符串 s
,请你找出其中不含有重复字符的 最长 子串 的长度。
class Solution {
public:
int lengthOfLongestSubstring(string s) {
map<char, int> mp;
int start = 0;
int result = 0;
for (int end = 0;end<s.size();end++)
{
if (mp.find(s[end])!=mp.end())//重复了
{
start = max(start,mp[s[end]]+1);
}
mp[s[end]] = end;
result = max(result, end-start+1);
}
return result;
}
};//滑动窗口思想,要存重复元素的下标
20.有效的括号
class Solution {
public:
bool isValid(string s) {
stack<char> stk;
unordered_map<char, char> pairs =
{{')','('},{']','['},{'}','{'}};
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();
}
};
21.合并两个有序链表
class Solution {
public:
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
ListNode* dummyhead = new ListNode(-1);
ListNode* cur = dummyhead;
while (list1 && list2)
{
if (list1->val <= list2->val)
{
cur->next = list1;
list1 = list1->next;
}
else if (list1->val > list2->val)
{
cur->next = list2;
list2 = list2->next;
}
cur = cur->next;
}
cur->next = !list1 ? list2 : list1;
return dummyhead->next;
}
};
70.爬楼梯
class Solution {
public:
int climbStairs(int n) {
if (n==1)
{
return 1;
}
else if (n==2)
{
return 2;
}
else
{
vector<int> dp(2);
dp[0] = 1;
dp[1] = 2;
for (int i = 3 ; i<=n;i++)
{
int temp = dp[1];
dp[1] = dp[0] + dp[1];
dp[0] = temp;
}
return dp[1];
}
}
};
94. 二叉树的中序遍历、前序遍历、后序遍历
递归方法
中序遍历
//递归方法
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
vector<int> result;
inOrder(root,result);
return result;
}
void inOrder(TreeNode* root, vector<int>& result)
{
if (!root)
{
return;
}
inOrder(root->left,result);
result.push_back(root->val);
inOrder(root->right,result);
}
};
时间复杂度:O(n),其中 n 为二叉树节点的个数。二叉树的遍历中每个节点会被访问一次且只会被访问一次。
空间复杂度:O(n)。空间复杂度取决于递归的栈深度,而栈深度在二叉树为一条链的情况下会达到 O(n)的级别。
非递归方法(迭代法)–栈
前序遍历(中左右)->压入中结点->循环:弹出,压入右节点,压入左节点
后序遍历(左右中):即为翻转的(中右左)->压入中结点->循环:弹出,压入左节点,压入右节点
中序遍历(左中右):一路向左,遇到空结点则弹出元素并向右走
class Solution {
public:
vector<int> inorderTraversal(TreeNode* root) {
stack<TreeNode*> stk;
vector<int> result;
TreeNode* cur = root;
while (cur!=nullptr || !stk.empty())
{
if (cur!=nullptr)
{
stk.push(cur);
cur = cur->left;
}
else
{
cur = stk.top();
stk.pop();
result.push_back(cur->val);
cur = cur->right;
}
}
return result;
}
};