目录
203、移除链表指定元素
204、质数的个数
205、相同结构的字符串
206、反转链表(双指针)
217、是否存在重复元素(哈希)
219、存在重复元素之间的距离
225、用队列实现栈
226、反转二叉树
231、是否是2的幂(位的与操作)
232、用栈实现队列
234、回文链表(用栈)
235、二叉搜索树的最近公共祖先
237、删除链表中的节点
242、字母相同单词不同
排序
哈希
数组
257、二叉树根到叶子的所有路径
258、各位相加
263、丑数
268、缺失的数字
278、第一个错误的版本(二分法)
283、把零都移到数组最后(双指针)
290、单词规律
292、Nim游戏
299、猜数字游戏
303、数组某区间内的和
326、是否是3的幂(递归)
342、是否是4的幂
344、反转字符串
345、反转字符串中的元音字母
349、两个数组的交集
350、两个数组的交集2
367、有效的完全平方数
371、两整数之和(不使用加减号)
374、猜数字大小(二分法)
383、赎金信
387、字符串中的第一个唯一字符
389、字符串找不同
392、是否子序列(双指针)
401、二进制手表
404、左叶子之和(递归)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
/*
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
if (!head)
return head;
head->next = removeElements(head->next, val);
return head->val == val ? head->next : head;
}
};
*/
class Solution {
public:
ListNode* removeElements(ListNode* head, int val) {
ListNode *first=new ListNode(0);
first->next=head;
ListNode *current=new ListNode(0);
current=first;
while(current->next!=NULL)
{
if(current->next->val==val)
{
ListNode *tmp=current->next;
current->next=current->next->next;
delete tmp;
}
else
current=current->next;
}
return first->next;
}
};
class Solution {
private:
bool isPrime(int x) {
if (x<2) return false;
for (int i=2;i*i<=x;i++)
if (x%i==0) return false;
return true;
}
public:
int countPrimes(int n) {
int cnt=0;
for (int i=2;i
class Solution {
public:
bool isIsomorphic(string s, string t) {
if (0 == s.size() && 0 == t.size())
{
return true;
}
for (int index = 0; index <= s.size() - 1; index++)
{
if (s.find(s[index]) != t.find(t[index]))
{
return false;
}
}
return true;
}
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* cur = NULL, *pre = head;
while (pre != NULL) {
ListNode* t = pre->next;
pre->next = cur;
cur = pre;
pre = t;
}
return cur;
}
};
class Solution {
public:
bool containsDuplicate(vector& nums) {
unordered_map mp;
for(int i:nums)
{
mp[i]++; //i对应的value值++
if(mp[i]>1) //i对应的value值大于1,则说明存在重复元素
return true;
}
return false;
}
};
class Solution {
public:
bool containsNearbyDuplicate(vector& nums, int k) {
if (0 == nums.size())
{
return false;
}
unordered_map map;
for(int index = 0; index <= nums.size() - 1; index++)
{
if(NULL != map.count(nums[index]) && index - map[nums[index]] <= k)
{
return true;
}
map[nums[index]] = index;
}
return false;
}
};
class MyStack {
public:
/** Initialize your data structure here. */
MyStack() = default;
/** Push element x onto stack. */
void push(int x) {
que.push(x);
for (int i = 0; i + 1 < que.size(); i++) {
que.push(que.front());
que.pop();
}
}
/** Removes the element on top of the stack and returns that element. */
int pop() {
int val = top();
que.pop();
return val;
}
/** Get the top element. */
int top() {
return que.front();
}
/** Returns whether the stack is empty. */
bool empty() {
return que.empty();
}
private:
queue que;
};
/**
* Your MyStack object will be instantiated and called as such:
* MyStack* obj = new MyStack();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->top();
* bool param_4 = obj->empty();
*/
/**
* 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* invertTree(TreeNode* root) {
if(!root) return nullptr;
root->left = invertTree(root->left);
root->right = invertTree(root->right);
swap(root->left, root->right);
return root;
}
};
// 利用与操作,若一个数n是2的幂次方,则2进制表达式一定为某一位为1,其余为0。
// 则n-1则会变成后面的数全部变成1,原来1的位置变成0
// 例子:n=16的2进制(000010000),则n-1=15的二进制(00001111),
// 则(n&n-1)=0
class Solution {
public:
bool isPowerOfTwo(int n) {
if(n<=0) return false;
if((n&n-1)==0) return true;
return false;
}
};
class MyQueue {
public:
/** Initialize your data structure here. */
stack main_s; //1.
stack help_s; //1.
MyQueue() {
}
/** Push element x to the back of queue. */
void push(int x) {
if (main_s.empty()){
main_s.push(x); //2.1
}
else{ //2.2
while (main_s.empty() == false){
help_s.push(main_s.top());
main_s.pop();
}
main_s.push(x);
while (help_s.empty() ==false){
main_s.push(help_s.top());
help_s.pop();
}
}
}
/** Removes the element from in front of queue and returns that element. */
int pop() { //3
int mid_v;
mid_v = main_s.top();
main_s.pop();
return mid_v;
}
/** Get the front element. */
int peek() {
return main_s.top(); //4
}
/** Returns whether the queue is empty. */
bool empty() {
return main_s.empty(); //5
}
};
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue* obj = new MyQueue();
* obj->push(x);
* int param_2 = obj->pop();
* int param_3 = obj->peek();
* bool param_4 = obj->empty();
*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
bool isPalindrome(ListNode* head) {
stack s;
ListNode *p = head;
while(p){
s.push(p->val);
p = p->next;
}
p = head;
while(p){
if(p->val != s.top()){
return 0;
}
s.pop();
p = p->next;
}
return 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* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root == nullptr) return nullptr;
if (p->val < root->val && q->val < root->val) return lowestCommonAncestor(root->left, p, q);
if (p->val > root->val && q->val > root->val) return lowestCommonAncestor(root->right, p, q);
return root;
}
};
/*
// 二叉树的公共祖先
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
if (root == nullptr || root == p || root == q) return root;
TreeNode* l = lowestCommonAncestor(root->left, p, q);
TreeNode* r = lowestCommonAncestor(root->right, p, q);
if (l && r) return root;
return l ? l : r;
}
};
*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void deleteNode(ListNode* node) {
if (!node->next) node = NULL;
else {
node->val = node->next->val;
node->next = node->next->next;
}
}
};
class Solution {
public:
bool isAnagram(string s, string t) {
sort(s.begin(), s.end()); //排序s
sort(t.begin(), t.end()); //排序t
return s.compare(t) == 0; //如果完全相同,返回0
}
};
class Solution {
public:
bool isAnagram(string s, string t) {
unordered_map hash_table;
for (int i = 0; i < s.size(); i++){
hash_table[s[i]] += 1;
}
for (int i = 0; i < t.size(); i++){
hash_table[t[i]] -= 1;
}
//遍历哈希表
for(auto it = hash_table.begin(); it != hash_table.end(); ++it){
if (it->second != 0 ) return false;
}
return true;
}
};
class Solution {
public:
bool isAnagram(string s, string t) {
char mytable[26] = {0};
for ( int i = 0; i < s.size(); i++){
mytable[ s[i] - 'a' ] += 1;
}
for ( int i = 0;i < t.size(); i++){
mytable[ t[i] - 'a' ] -= 1;
}
for ( int i = 0; i< 26; i++){
if (mytable[i] != 0) return false;
}
return true;
}
};
/**
* 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 binaryTreePaths(TreeNode* root) {
vector res;//用以保存返回值
if(!root)//防止初值为NULL
{
return res;
}
if(!root->left && !root->right)//对于叶子节点的处理
{
res.push_back(to_string(root->val));//在返回值中填入当前叶子的值
}
else//对于非叶子节点的处理
{
if(root->left)//对左子树的处理
{
vector left = binaryTreePaths(root->left);//将返回值保存在left中
res.insert(res.end(), left.begin(), left.end());//将left追加到res的末尾
}
if(root->right)//右子树同理
{
vector right = binaryTreePaths(root->right);
res.insert(res.end(), right.begin(), right.end());
}
for(int i = 0; i < res.size(); i++)//对于非叶子节点,需要将路径表示出来
{
res[i].insert(0, "->");
res[i].insert(0, to_string(root->val));
}
}
return res;
}
};
class Solution {
public:
// 方法1:暴力法,需要两个循环,时间复杂度近似为 O(n^2),n为num长度。
int addDigits1(int num){
int sum;
while(num >= 10){
sum = 0;
while( num ){
sum += num % 10;
num /= 10;
}
num = sum;
}
return num;
}
// 方法2: 总结规律法。 时间复杂度为O(1)
// 设三位数 n = 100a + 10b + c 则 n - ( a+b+c) = 99a + 9b 也就是说每次n的各位求和结果与原n相比,
// 都减少了9的倍数(它俩的差是9的倍数),所以n对9取余的结果就是所求结果。
// n为其他位数时等同,注意 n > 0 且 n % 9 == 0 时,结果应为9
int addDigits2(int num){
int res = num % 9;
if( res == 0 && num > 0)
return 9;
else
return res;
}
};
class Solution {
public:
bool isUgly(int num) {
while(num){
if(num%2==0) num/=2;
else if(num%5==0) num/=5;
else if(num%3==0) num/=3;
else break;
}
return num==1;
}
};
class Solution{
public:
int missingNumber(vector& nums){
int length=nums. size();
int result=(length+1)* length/2;
for(int e: nums)
result-=e;
return result;
}
};
// The API isBadVersion is defined for you.
// bool isBadVersion(int version);
class Solution {
public:
int firstBadVersion(int n) {
int low = 1, high = n;
while(low < high)
{
int mid = low + (high - low)/2 ; //防止直接相加溢出
if(isBadVersion(mid)) high = mid ;
else low = mid + 1;
}
return low;
}
};
class Solution {
public:
void moveZeroes(vector& nums) {
int i=0; //记录非0元素的后一个位置,初始为0
for(int j=0;j
class Solution {
public:
bool wordPattern(string pattern, string str) {
// 分割字符串
vector words;
string s;
for (int i = 0; i < str.size(); i++)
if (str[i] == ' ') {
if (s.size())
words.push_back(s);
s = "";
} else
s += str[i];
if (s.size())
words.push_back(s);
// 分割字符串 end
if(words.size() != pattern.length())
return false;
for(int i = 0; i < pattern.length(); i++)
for(int j = i + 1; j < pattern.length(); j++){
if((pattern[i] == pattern[j]) && (words[i] != words[j]) ||
(pattern[i] != pattern[j]) && (words[i] == words[j]))
return false;
}
return true;
}
};
// 1 true
// 2 true
// 3 true
// 4 false
// 5 true 不难想到,你先拿走一个,问题变为:对手先手拿4块石头,由子问题4知对手必败,你必胜。为true
// 6 true 同理 可以拿走两个 转化为子问题4的非
// 7 true 同理
// 8 false 不论拿走几个都将转变为5 6 7 的非
// ...
// 结论,只要手中石头是4的倍数,你必输。
class Solution {
public:
bool canWinNim(int n) {
if(n%4==0)return false;
return true;
}
};
class Solution {
public:
string getHint(string secret, string guess) {
int a = 0, b = 0;
unordered_map ump;
for (int i = 0; i < secret.size(); ++i) {
// 统计位置和字符完全相同数个数为 a 并将第一个字符串中数字出现次数建立哈希表。
if (secret[i] == guess[i]) ++a;
++ump[secret[i]];
}
for (int i = 0; i < guess.size(); ++i) {
if (ump[guess[i]] > 0) {
// 遍历猜数各个数字是否出现过,如果出现则递增 b 个数,同时将字符出现次数减 1 。
++b;
--ump[guess[i]];
}
}
// 从b中减去位置和字符完全相同数字个数a。
if (a > 0) b -= a;
return to_string(a) + "A" + to_string(b) + "B";
}
};
class NumArray {
public:
NumArray(vector& nums) : m_map(nums.size())
{
int sum = 0;
for (int i = 0; i < nums.size(); ++i)
{
sum += nums.at(i);
m_map[i] = sum;
}
}
int sumRange(int i, int j) {
return m_map[j] - (i == 0 ? 0 : m_map[i - 1]); // i == 0
}
private:
vector m_map;
};
/**
* Your NumArray object will be instantiated and called as such:
* NumArray* obj = new NumArray(nums);
* int param_1 = obj->sumRange(i,j);
*/
class Solution
{
public:
bool isPowerOfThree(int n)
{
if(n <= 0)
return false;
else if(n == 1)
return true;
else
return n % 3 == 0 && isPowerOfThree(n / 3);
}
};
class Solution {
public:
bool isPowerOfFour(int num) {
if(num==1) return true;
else if(num==0) return false;
else return isPowerOfFour(num/4)&&num%4==0;
}
};
class Solution {
public:
void reverseString(vector& s) {
int i=0, j=s.size()-1;
char tmp;
while(i
class Solution {
public:
string reverseVowels(string s) {
int i = 0, j = s.length() - 1;
while (i < j) {
if (! isornot(s[i])) {i ++; continue;}
if (! isornot(s[j])) {j --; continue;}
swap (s[i++],s[j--]);
}
return s;
}
bool isornot(char c) {
return (c == 'a' || c == 'A' || c == 'i' || c == 'I' || c == 'o' || c == 'O' || c == 'u' || c == 'U' || c == 'e' || c == 'E') ;
}
};
class Solution {
public:
vector intersection(vector& nums1, vector& nums2) {
if(nums1.empty()) return nums1;
if(nums2.empty()) return nums2;
vector res;
map map_1;
for(int i=0 ;i
class Solution {
public:
vector intersect(vector& nums1, vector& nums2) {
vectorrec;
unordered_mapmap;
for(int i =0;i0)
{
rec.push_back(nums2[i]);
map[nums2[i]]-=1;
}
return rec;
}
};
// 1 4=1+3 9=1+3+5 16=1+3+5+7以此类推,模仿它可以使用一个while循环,不断减去一个从1开始不断增大的奇数,若最终减成了0,说明是完全平方数,否则,不是。
// 原理:(n+1)^2-n^2=2n+1
class Solution
{
public:
bool isPerfectSquare(int num)
{
int num1 = 1;
while(num > 0)
{
num -= num1;
num1 += 2;
}
return num == 0;
}
};
/*
// 折半查找
class Solution {
public:
bool isPerfectSquare(int num) {
long left = 1, right = num;
while(left <= right)
{
long mid = (left + right) / 2;
if(mid * mid > num)
right = mid - 1;
else if(mid * mid < num)
left = mid + 1;
else
return true;
}
return false;
}
};
*/
class Solution {
public:
int getSum(int a, int b) {
while( b != 0){
// 先做异或运算,结果为进位标志
int temp = a ^ b;
// 在做与运算并左移1位,在将没有进位的结果与与运算的结果做异或运算得结果。
b = ((unsigned int)(a & b) << 1);
// a为结果,b为进位结果,不断检查b是否为0判断是否还有进位。
a = temp;
}
return a;
}
};
/**
* Forward declaration of guess API.
* @param num your guess
* @return -1 if num is lower than the guess number
* 1 if num is higher than the guess number
* otherwise return 0
* int guess(int num);
*/
class Solution {
public:
int guessNumber(int n)
{
int i = 1, j = n;
int t;
while (i <= j)
{
t = i+(j - i) / 2;//不能写为(i+j)/2,会溢出
if (guess(t) == 0)
return t;
else
if (guess(t) == 1)
i = t + 1;
else
j = t - 1;
}
return -1;//未找到
}
};
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
int hash[26] = {0};
for (char c : magazine) hash[c - 'a'] += 1;
for (char c : ransomNote)
if ((hash[c - 'a'] -= 1) < 0) return false;
return true;
}
};
class Solution {
public:
int firstUniqChar(string s) {
int hash[26]={0};
for(char n:s)
hash[n-'a']++; //n-'a',得到该字母在数组中对应的索引
for(int i=0;i
class Solution {
public:
char findTheDifference(string s, string t)
{
int hash[26] = { 0 };
for (int i = 0; i < s.size(); ++i)
hash[s[i] - 'a']++;
for (int i = 0; i < t.size(); ++i)
{
hash[t[i] - 'a']--;
if (hash[t[i] - 'a'] == -1)
return t[i];
}
return -1;
}
};
/*
// ASCII码之差
class Solution {
public:
char findTheDifference(string s, string t) {
int ans = 0;
for (char ch : t) ans += ch;
for (char ch : s) ans -= ch;
return (char)ans;
}
};
*/
class Solution {
public:
bool isSubsequence(string s, string t) {
int i = 0;
int j = 0;
while (i < s.size() && j < t.size())
{
if (s.at(i) == t.at(j))
{
++i;
++j;
}
else
{
++j;
}
}
if (i == s.size())
{
return true;
}
return false;
}
};
class Solution {
public:
// 不要思考n个1能构成多少时间,而是应该思考一个时间由多少个1构成
// 统计二进制中1的个数
int count1(int n)
{
int cnt = 0;
while(n != 0)
{
n = n & (n - 1);
cnt++;
}
return cnt;
}
vector readBinaryWatch(int num)
{
vector res;
//遍历0:00到11:59的每个时间
for(int i = 0; i < 12; i++)
{
for(int j = 0; j < 60; j++)
{
if(count1(i) + count1(j) == num)
{
res.push_back(to_string(i) + ":" + (j < 10 ? "0" + to_string(j) : to_string(j)));
}
}
}
return res;
}
};
/**
* 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 sumOfLeftLeaves(TreeNode* root) {
if(root==NULL)return 0;
if(root->left!=NULL)
{
if(root->left->left==NULL&&root->left->right==NULL)
return root->left->val+sumOfLeftLeaves(root->right);
else return sumOfLeftLeaves(root->left)+sumOfLeftLeaves(root->right);
}
else if(root->right!=NULL)return sumOfLeftLeaves(root->right);
else return 0;
}
};