目录
1、两数之和(vector)
暴力搜索
两遍哈希表(空间换时间)
一遍哈希表(边判断边加入)
7、整数反转
9、回文数(整数)
13、罗马数字转整数
14、最长公共前缀
20、有效的括号(用栈)
21、合并两个有序链表
递归
迭代
26、删除排序数组中的重复项(双指针)
27、移除数组的一个元素
28、实现strStr( )(字符串包含问题)(双指针)
35、在有序数组搜索插入位置(二分查找法)
38、外观数列count and say(双指针)
53、最大子序和
暴力法
动态规划
58、最后一个单词的长度
66、加一(数字是以百十个的数组存储的)
67、二进制求和
69、x的平方根(取整)(二分)
70、爬楼梯的方法个数(抽象出来就是一个斐波那契数列)
83、删除排序链表的重复元素
88、合并两个有序数组(双指针)
100、相同的树(是二叉树)(递归)
101、对称二叉树(递归)
104、二叉树的最大深度(递归)
107、二叉树的层次遍历(递归)
108、将有序数组转换为二叉搜索树(递归)
110、判断是否是平衡二叉树(递归)
111、二叉树的最小深度(递归)
112、是否存在和为某值的路径(递归)
118、杨辉三角-生成
119、杨辉三角-返回特定行
121、买卖股票的最佳时机-交易一次
122、买卖股票的最佳时机-交易多次
125、验证回文串(双指针)
136、只出现一次的数字
141、环形链表
155、最小栈(增加辅助栈)
160、相交链表
167、两数之和(有序数组)(双指针)
168、Excel表名称(数字到字母)(二十六进制)
169、出现最多次的元素(投票法)
171、Excel表序号(字母到数字)(二十六进制)
172、阶乘后有多少个零(找5)
189、旋转数组(三次翻转)
190、颠倒二进制位(按位操作)
191、位1的个数
198、打家劫舍(奇数偶数项的和)(动态规划)
202、快乐数
class Solution
{
public:
vector twoSum(vector& nums, int target)
{
vector twoSum;
for(int i=0;i
class Solution
{
public:
vector twoSum(vector& nums, int target)
{
vector twoSum;
map tmpmap;
for (int i = 0; i < nums.size(); i++)
{
tmpmap[nums[i]] = i;//tmpmap[键值] = 下标顺序
}
for (int i = 0; i < nums.size(); i++)
{
//如果存在对应值 且 其对应值的下标不是他自己
if (tmpmap.count(target - nums[i]) == 1 && tmpmap[target-nums[i]]!=i)
{
twoSum.push_back(i);
twoSum.push_back(tmpmap[target - nums[i]]);
break;
}
}
return twoSum;
}
};
class Solution
{
public:
vector twoSum(vector& nums, int target)
{
vector twoSum;
map tmpmap;
for (int i = 0; i < nums.size(); i++)
{
//如果存在对应值 且 其对应值的下标不是他自己
if (tmpmap.count(target - nums[i]) == 1 && tmpmap[target-nums[i]]!=i)
{
twoSum.push_back(i);
twoSum.push_back(tmpmap[target - nums[i]]);
break;
}
tmpmap[nums[i]] = i;//tmpmap[键值] = 下标顺序
}
return twoSum;
}
};
class Solution {
public:
int reverse(int x) {
int rev = 0;
while (x != 0) {
int pop = x % 10;
x /= 10;
//判断范围是否合法
if (rev > INT_MAX/10 || (rev == INT_MAX / 10 && pop > 7)) return 0;
if (rev < INT_MIN/10 || (rev == INT_MIN / 10 && pop < -8)) return 0;
rev = rev * 10 + pop;
}
return rev;
}
};
可以使用第7题的方法先整数反转再对比是否相等
class Solution {
public:
bool isPalindrome(int x) {
if(x<0) return false;
if(x != reverse(x)) return false;
return true;
}
int reverse(int x) {
int rev = 0;
while (x != 0) {
int pop = x % 10;
x /= 10;
//判断范围是否合法
if (rev > INT_MAX/10 || (rev == INT_MAX / 10 && pop > 7)) return 0;
if (rev < INT_MIN/10 || (rev == INT_MIN / 10 && pop < -8)) return 0;
rev = rev * 10 + pop;
}
return rev;
}
};
class Solution {
public:
int romanToInt(string s) {
unordered_map m = {
{"I", 1}, {"IV", 4}, {"IX", 9}, {"V", 5},
{"X", 10}, {"XL", 40}, {"XC", 90}, {"L", 50},
{"C", 100}, {"CD", 400}, {"CM", 900}, {"D", 500},
{"M", 1000}
};
int r = 0;
for(int i=0; i
class Solution {
public:
string longestCommonPrefix(vector& strs) {
string res = strs.empty() ? "" : strs[0];
for (string s : strs)
while (s.find(res) != 0) // 返回下标非起始
res = res.substr(0, res.length() - 1);
return res;
}
};
class Solution {
public:
bool isValid(string s)
{
stack stk;
int length = s.size();
//奇数个一定不能成对
if(length % 2 != 0) return false;
for(int i = 0;i < length;i++)
{
char popChar;
switch(s[i])
{
//左括号先进栈等右括号配对
case '(':
case '[':
case '{':
stk.push(s[i]);
break;
case ')':
//注意栈为空
if(stk.empty()) return false;
if(stk.top() == '(') stk.pop();
break;
case ']':
//注意栈为空
if(stk.empty()) return false;
if(stk.top() == '[') stk.pop();
break;
case '}':
//注意栈为空
if(stk.empty()) return false;
if(stk.top() == '{') stk.pop();
break;
default:
return false;
break;
}
}
if (stk.empty()) return true;
else return false;
}
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
// -----递归------
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2)
{
if(l1 == NULL) return l2;
if(l2 == NULL) return l1;
if(l1->val < l2->val)
{
l1->next = mergeTwoLists(l1->next,l2);
return l1;
}
else
{
l2->next = mergeTwoLists(l1,l2->next);
return l2;
}
}
};
class Solution
{
public:
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2)
{
ListNode *result = new ListNode(-1); //哑节点简化代码
ListNode *workNode = result;
while (l1 != nullptr && l2 != nullptr)
{
if (l1->val <= l2->val)
{
workNode->next = l1;
l1 = l1->next;
}
else
{
workNode->next = l2;
l2 = l2->next;
}
workNode = workNode->next;
}
workNode->next = l1 != nullptr ? l1 : l2;
return result->next;
}
};
class Solution {
public:
int removeDuplicates(vector& nums)
{
if (nums.size() < 2) return nums.size();
int cur = 0;
for(int i = 1;i < nums.size();i++)
{
if(nums[i] != nums[cur]) nums[++cur] = nums[i];
}
return cur+1;
}
};
class Solution {
public:
int removeElement(vector& nums, int val) {
int n=nums.size();
for(int i=0;i
class Solution
{
public:
int strStr(string haystack, string needle)
{
int l1 = haystack.size();
int l2 = needle.size();
// 当 needle 是空字符串时我们应当返回 0
if(l2 == 0) return 0;
for(int i = 0; i <= l1 - l2; i++)
{
int j;
for(j = 0;j
class Solution {
public:
int searchInsert(vector& nums, int target) {
if(nums.empty()) return 0;
int high = nums.size()-1;
int low = 0;
int mid;
while(lowtarget) high = mid-1;
if(nums[mid]
class Solution {
public:
string countAndSay(int n) {
if(n==1) return "1";
string pre=countAndSay(n-1),ans;
int len=pre.size();
int i=0;
for(int j=0;j<=len;)
{
if(pre[i]==pre[j])
{
j++;
continue;
}
else
{
ans+=to_string(j-i)+pre[i];
i=j;
}
}
return ans;
}
};
class Solution {
public:
int maxSubArray(vector &nums) {
int size = nums.size();
int res = INT32_MIN;
for (int i = 0; i < size; ++i) {
int sum = 0;
for (int j = i; j < size; ++j) {
sum += nums[j];
res = max(res, sum);
}
}
return res;
}
};
Class Solution
public:
int maxSubArray(int[] nums)
{
if (nums == null) {
return 0;
}
int max = nums[0]; // 全局最大值
int subMax = nums[0]; // 前一个子组合的最大值
for (int i = 1; i < nums.length; i++) {
if (subMax > 0) {
// 前一个子组合最大值大于0,正增益
subMax = subMax + nums[i];
} else {
// 前一个子组合最大值小于0,抛弃前面的结果
subMax = nums[i];
}
// 计算全局最大值
max = Math.max(max, subMax);
}
return max;
}
};
class Solution {
public:
int lengthOfLastWord(string s){
int length = 0; // 当前单词长度
bool isWord = false; // 是否遇到了单词
for(int i = s.length() - 1; i >= 0; i--)
{
if( s[i] != ' ' ){
isWord = true;
length++;
}else if( s[i] == ' ' && isWord ){
return length;
}
}
return length;
}
};
class Solution {
public:
vector plusOne(vector& digits) {
for (int i = (int)digits.size() - 1; i >= 0; i--) {
if (digits[i] == 9) {
digits[i] = 0;
}
else {
digits[i]++;
break;
}
}
if (digits[0] == 0) {
digits.push_back(0);
digits[0] = 1;
}
return digits;
}
};
class Solution {
public:
string addBinary(string a, string b) {
int al = a.size();
int bl = b.size();
//让两个字符串等长,若不等长,在短的字符串前补零,否则之后的操作会超出索引
while(al < bl)
{
a = '0' + a;
al++;
}
while(al > bl)
{
b = '0' + b;
bl++;
}
//从后到前遍历所有的位数,同位相加
//'1’-'0' =1
int carry = 0; //进位
for (int i = a.size() - 1; i >= 0; i--)
{
int sum = a[i] - '0' + b[i] - '0' + carry;
a[i] = (sum) % 2+'0';//本位数值
carry = sum / 2;//进位更新
}
if (carry > 0)//有溢出
a = '1' + a;
return a;
}
};
class Solution {
public:
int mySqrt(int x) {
if(x < 2) return x;
int l = 0, h = x;
while(l < h){
int m = (l + h) / 2;
if(m > x / m) h = m; else l = ++m;
}
return l - 1;
}
};
/*
每次可以爬1或2个台阶,则第到达第i台阶前必定经过 第i-1台阶或第i-2台阶
设stair[i]表示到达第i台阶的方法种数
则stair[i] = stair[i - 1] + stair[i - 2]
即到达第i-1台阶的种数加上第i-2台阶的种数
边界条件:
stair[0] = 1
stair[1] = 1
其实抽象出来就是一个斐波那契数列
*/
class Solution {
public:
int climbStairs(int n) {
vector stair(n+1, 0);
stair[0] = stair[1] = 1;
for(int i = 2; i
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head)
{
if(head == NULL||head->next == NULL)
return head;
ListNode* p=head;
while(p->next != NULL && p != NULL)
{
if(p->val == p->next->val) p->next=p->next->next;
else p=p->next;
}
return head;
}
};
class Solution {
public:
void merge(vector& nums1, int m, vector& nums2, int n)
{
for (int i = m - 1, j = n - 1, k = m + n - 1; k >= 0; k--)
{
//如果num2中已经全部合并完毕
//或i中还有元素且此时num1大于num2的
if (j < 0 || (i >= 0&&nums1[i] > nums2[j]))
nums1[k] = nums1[i--];
else
nums1[k] = nums2[j--];
}
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if(p==NULL&&q==NULL) return true;
else if(p==NULL||q==NULL) return false;
if(p->val!=q->val) return false;
return isSameTree(p->right, q->right) && isSameTree(p->left, q->left);
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSymmetric(TreeNode* root) {
return ismirror(root,root);
}
bool ismirror(TreeNode* p,TreeNode* q){
if(!p&&!q)//都为NULL
return true;
else if(!p||!q)//有一个为NULL
return false;
return (p->val==q->val)&&ismirror(p->left,q->right)&&ismirror(p->right,q->left);
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int maxDepth(TreeNode* root) {
if(root == NULL)
return 0;
return max(maxDepth(root->left),maxDepth(root->right))+1;
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector> levelOrderBottom(TreeNode* root) {
int n = getDep(root);
vector> ans(n, vector());
dfs(root, 0, ans, n - 1);
return ans;
}
void dfs(TreeNode *root, int depth, vector>& ans, int n) {
if (root == NULL) return ;
ans[n - depth].push_back(root->val); // 倒着装 n - depth
dfs(root->left, depth + 1, ans, n);
dfs(root->right, depth + 1, ans, n);
}
int getDep(TreeNode *root) { // 求树的高度
if (root == NULL) return 0;
return max(getDep(root->left), getDep(root->right)) + 1;
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* sortedArrayToBST(vector& nums)
{
if(nums.empty()) return nullptr;
return helper(nums,0,nums.size()-1);
}
TreeNode* helper(vector& nums, int left, int right)
{
if(left > right)
return nullptr;
int mid = (left+ right) / 2;
TreeNode *root = new TreeNode(nums[mid]);
root->left = helper(nums, left,mid -1);
root->right = helper(nums,mid+1, right);
return root;
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isBalanced(TreeNode* root) {
if(!root) return true;
int d = abs(getDep(root->left)-getDep(root->right)); //当前节点的左右子树的高度差
return (d<=1) && (isBalanced(root->left)) && (isBalanced(root->right));
}
int getDep(TreeNode *root) { // 求树的高度
if (root == NULL) return 0;
return max(getDep(root->left), getDep(root->right)) + 1;
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
int minDepth(TreeNode* root) {
if (!root) return 0; //递归结束
int left = minDepth(root->left); //计算左子树的高度
int right = minDepth(root->right); //计算右子树的高度
if (!left || !right) return left + right + 1; //如果有一个空,则+1
return min(left, right) + 1; //否则最小值+1
}
};
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
if(root == nullptr) return false;
if(root->left == nullptr && root->right == nullptr && root->val == sum) return true;
return hasPathSum(root->left,sum - root->val)
|| hasPathSum(root->right,sum - root->val);
}
};
class Solution {
public:
vector> generate(int numRows) {
if(numRows == 0) return {};
vector> rs;
for (int i = 0; i < numRows; i++) {
//仔细看图 每一行 第一个 最后一个 都是1
//所以初始化都为1 然后遍历的时候避开这2个,可以避免一些判断
vector vec(i+1,1);
for (int j = 1; j < i; j++) {
vec[j] = rs[i-1][j-1] + rs[i-1][j];
}
rs.push_back(vec);
}
return rs;
}
};
class Solution {
public:
vector getRow(int rowIndex)
{
vector result;
for(int i = 0; i <= rowIndex; ++i){
result.push_back(1);
for(int j = i - 1; j > 0; --j){
result[j] += result[j - 1];
}
}
return result;
}
};
class Solution {
public:
int maxProfit(vector& prices) {
if(prices.size() <= 1)
return 0;
int minP = prices[0], maxP = 0;
for(int i = 1; i < prices.size(); i++) {
maxP = max(maxP, prices[i] - minP);
minP = min(minP, prices[i]);
}
return maxP;
}
};
class Solution {
public:
int maxProfit(vector& prices) {
int ans=0;
for(int i=1;iprices[i-1])
{
ans+=prices[i]-prices[i-1];
}
}
return ans;
}
};
class Solution {
public:
bool isPalindrome(string s)
{
// 双指针
if(s.size() <= 1) return true;
int i = 0, j = s.size() - 1;
while(i < j)
{
// 排除所有非字母或数字的字符
while(i < j && !isalnum(s[i]))
i++;
while(i < j && !isalnum(s[j]))
j--;
if(tolower(s[i++]) != tolower(s[j--])) //统一转换成小写字母再比较
return false;
}
return true;
}
};
class Solution {
public:
int singleNumber(vector& nums) {
unordered_set bobo;
int ans;
for(auto i : nums){
if(bobo.count(i)) bobo.erase(i);
else bobo.insert(i);
}
for(auto j : bobo) ans = j;
return ans;
}
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool hasCycle(ListNode *head) {
while(head)
{
if(head == head->next) return true;
if(head->next) head->next = head->next->next;
head = head->next;
}
return false;
}
};
class MinStack {
public:
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
stackdata.push(x);
if(stackmin.empty()) { stackmin.push(x); }
else if(x stackdata;
stack stackmin;
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(x);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->getMin();
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//if (headA == NULL || headB == NULL) return NULL;
ListNode *pA = headA, *pB = headB;
while (pA != pB) {
pA = pA == NULL ? headB : pA->next;
pB = pB == NULL ? headA : pB->next;
}
return pA;
}
};
class Solution {
public:
vector twoSum(vector& numbers, int target) {
int i = 0, j = numbers.size() - 1;
while (i < j) {
if (numbers[i] + numbers[j] == target) return {i + 1, j + 1};
if (numbers[i] + numbers[j] > target) j --;
else i ++;
}
return {};
}
};
class Solution {
public:
string convertToTitle(int n) {
string res;
int temp = 0;
while(n!=0)
{
n--;
temp = n%26;
res =(char)(temp+'A') + res;
n = n/26;
}
return res;
}
};
class Solution {
public:
int majorityElement(vector& nums) {
/*//排序:中间元素
sort(nums.begin(),nums.end());
return nums[nums.size()/2];
*/
/*//哈希表
map mp;
for(int i=0;inums.size()/2)
return nums[i];
}
return -1;
*/
//投票法:相同计数器加1,不相同计数器减1,最终剩下的数为众数
int count=0;
int n;
for(int i=0;i
class Solution {
public:
int titleToNumber(string s) {
int i=0;
long ans=0;
while(s[i]!='\0'){
ans=ans*26+s[i]-'A'+1;
i++;
}
return ans;
}
};
class Solution {
public:
int trailingZeroes(int n) {
int ans = 0;
while (n > 0) {
ans += n / 5;
n /= 5;
}
return ans;
}
};
class Solution {
public:
void rotate(vector& nums, int k) {
int len=nums.size();
//reverse翻转的是[begin,end)区间
reverse(nums.begin(), nums.end() - k%len); //翻转A区间
reverse(nums.end()- k%len,nums.end()); //翻转B区间
reverse(nums.begin(),nums.end()); //整体翻转
}
};
class Solution {
public:
uint32_t reverseBits(uint32_t n) {
uint32_t res = 0;
int index = 32; //操作32次移位操作
while(index--)
{
res<<=1;//结果左移一位,空出位置与n最后一位相加
res+=n&1; //加上n的最后一位
n>>=1; //n右移一位,供下一轮与结果相加
}
return res;
}
};
class Solution {
public:
int hammingWeight(uint32_t n) {
int ans = 0;
while(n){
if(n & 1) ++ans;
n >>= 1;
}
return ans;
}
};
class Solution {
public:
int rob(vector& nums) {
int size = nums.size();
if(size == 0) return 0;
if(size == 1) return nums[0];
if(size == 2) return max(nums[0], nums[1]);
vector dp(size, 0);
dp[0] = nums[0];
dp[1] = max(nums[1], nums[0]);
for(int i=2;i
class Solution {
public:
bool isHappy(int n) {
while(n>=10){
n = next(n);
}
// 若把1自己也作为循环去思考,那么所有的循环都至少有一位数的时候这个 不知道该如何证明
// 一位数的快乐数就1和7
return n==1 || n==7;
}
int next(int n){
int res = 0;
while(n){
int k = n%10;
res += k*k;
n /= 10;
}
return res;
}
};