Leetcode学习过程(持续更新)

现在是2019/9/17,本学期刚开始发现压力不是很大,想尽快提升一下编程能力,于是乎准备开始Leetcode之旅,根据时间,安排学习其他人的方法。
771.宝石与石头(哈希表)

class Solution {
public:
	int numJewelsInStones(string J, string S) {
		set<int> s;
		for (int i = 0; i < J.length(); i++){
			s.insert(J[i]);
		}
		int count = 0;
		for (int i = 0; i < S.length(); i++){
			if (s.find(S[i]) != s.end())
				count++;
		}
		return count;
	}
};

涉及知识:c++中set用法
c++ set集合的使用方法详解
C++ STL set和multiset的使用
个人理解:先把第一个字符串J中的元素都插入到容器s中,之后通过容器自带的find函数,找到字符串S中的相同元素。
String.find()函数

class Solution {
public:
	int numJewelsInStones(string J, string S) {
		int count = 0;
		for (int i = 0; i < S.length(); i++){
			if (J.find(S[i]) != J.npos)
				count++;
		}
		return count;
	}
};

string 类提供了 6 种查找函数,每种函数以不同形式的 find 命名。
这些操作全都返回 string::size_type 类型(索引)的值,以下标形式标记查找匹配所发生的位置;
或者返回一个名为 string::npos 的特殊值,说明查找没有匹配。string 类将 npos 定义为保证大于任何有效下标的值。
1108. IP 地址无效化
C++ replace() 函数用法
0ms C++ 逆遍历

class Solution {
public:
    string defangIPaddr(string address) {
        for(int i = address.size(); i >= 0; i--){
            if(address[i] == '.'){
                address.replace(i, 1, "[.]");
            }
        }
        return address;
    }
};

逆遍历字符串并替换 . 为 [.]
本题若正遍历,每次替换完,下一个字符会变成 .,进入死循环
1109. 删除链表中的节点
Leetcode学习过程(持续更新)_第1张图片
c++中指针node要用->访问数据元素。

  1. 二叉搜索树的范围和
    Leetcode学习过程(持续更新)_第2张图片
/**
 * 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 sum = 0;
    int rangeSumBST(TreeNode* root, int L, int R) {
        dfs(root,L,R);
        return sum;
    }
    void dfs(TreeNode* node,int L, int R)
    {
        if(node!=NULL)
        {
            if(node->val>=L&&node->val<=R)
            {
                 sum+=node->val;
                 dfs(node->right,L,R);
                 dfs(node->left,L,R);
            }
            if(node->val<L)
                dfs(node->right,L,R);
            if(node->val>R)
                dfs(node->left,L,R);
        }
    }
};

堆栈遍历(较慢):

class Solution {
public:
    int sum = 0;
    int rangeSumBST(TreeNode* root, int L, int R) {
        stack<TreeNode *> Stack;
        Stack.push(root);
        while(!Stack.empty())
        {
            TreeNode *tmp = Stack.top();
            Stack.pop();
            if(tmp!=NULL)
            {
                    if(tmp->val>=L&&tmp->val<=R)
                {
                    sum+=tmp->val;
                    Stack.push(tmp->left);
                    Stack.push(tmp->right);
                }
                else if(tmp->val<L)
                    Stack.push(tmp->right);
                else
                    Stack.push(tmp->left);
            }   
        }
        return sum;
    }
};
  1. 删除最外层的括号
    思路:遍历字符串,遇到左括号就入栈,遇到右括号就出栈,每次栈空的时候,都说明找到了一个原语,记录下每个原语的起始位置和结束位置,取原字符串在原语的起始位置+1到原语的结束位置的子串便得到原语删除了最外层括号的字符串,拼接,即可解出答案。
class Solution {
public:
    string removeOuterParentheses(string S) {
        string result;      //存放结果,可用append方法
        bool flag=false;    //如果正在遍历的过程是一个有效字符串就置为False,该有效字符串遍历结束置为True
        stack<char> Stack;  
        int begin,end;      //标记一个有效字符串的起始和结束位置,即外层括号位置
        for(int i=0;i<S.length();i++)
        {
            if(S[i]=='(')      //遇到左括号入栈
            {
                Stack.push(S[i]);
                if(!flag)       //如果是一个新的有效字符串起始,就记录begin
                {
                    begin=i;
                    flag=true;
                }
            }
            else
            {
                Stack.pop();    //如果是右括号就出栈
                if(Stack.empty())   //如果栈空说明一个有效字符串结束
                {
                    end=i;      //记录终止位置
                    flag=false;
                    result+=S.substr(begin+1,end-begin-1);  //送入结果
                }
            }
        }
        return result;
    }
};

超级简化版
如果栈不空就说明在一个有效字符串内部,就加上该字符,3个if的顺序不能颠倒(难点)

class Solution {
public:
	string removeOuterParentheses(string S) {
		string res = "";
		stack<char> mystack;
		for (int i = 0; i < S.size(); i++) {
			if (S[i] == ')')
				mystack.pop();
			if (!mystack.empty())
				res+=S[i];
			if (S[i] == '(')
				mystack.push('(');

		}
		return res;
	}
};
  1. 转换成小写字母
class Solution {
public:
    string toLowerCase(string str) {
        if(str.empty())
            return NULL;
        for(int i=0;i<str.length();i++)
        {
            if(str[i]>='A'&&str[i]<='Z')
            {
                str[i]+=32;
            }
        }
        return str;
    }
};
  1. 合并二叉树
    思路
    AB两棵树 同步递归 用B更新A并返回A
    递归过程:
    如果A当前节点为空 返回B的当前节点
    如果B当前节点为空 返回A的当前节点
    (此情况已经包含在上述两种)AB的两个当前节点都为空 返回null
    都不为空 则将B的val 加到A的val上 返回当前节点
class Solution {
public:
    TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) {
        if(t1==NULL&&t2==NULL)
            return NULL;
        else if(t1==NULL)
            return t2;
        else if(t2==NULL)
            return t1;
        else
        {
            t1->val+=t2->val;
            t1->left=mergeTrees(t1->left,t2->left);
            t1->right=mergeTrees(t1->right,t2->right);
            return t1;
        }
    }
};
  1. 唯一摩尔斯密码词
    传入参数:vector& words
    1.其中“&”为引用,相当于给传入的参数换了一个名字叫words,引用用法举例:
//引用
int main()
{
int a = 3;
int &b = a;
int c = a;
cout << "a:" << a << endl;
cout << "b:" << b << endl;
cout << "c:" << c << endl;
b = 10;
cout << "a:" << a << endl;
cout << "b:" << b << endl;
cout << "c:" << c << endl;
cout << "&a:" << &a << endl;
cout << "&b:" << &b << endl;
cout << "&c:" << &c << endl;
system("pause");
}
//结果:
a:3
b:3
c:3
a:10
b:10
c:3
&a:0019FD74
&b:0019FD74 //这里的“&”为取址,可以看到a,b这两个数是相同地址的
&c:0019FD5C
//& 引用 :比如说,一个人有多少外号,但都是指这个人,引用也是这样。如果b的值改动了,也就代表了a的值改动了

一个引用传参的例子:

//引用传入函数参数
void fun(int &a, int &b)
{
int c = 0;
c = a;
a = b;
b = c;
}
int main()
{
int a = 1;
int b = 2;
cout << a << "," << b << endl;
fun(a, b);//a,b交换
cout << a << "," << b << endl;
system("pause");
return 0;
}
//本质上是把main()中的a,b变量 换了个名字,即:函数中的a,b,函数中的a,b地址与main()中的地址是一样的。如果函数中的a,b值改变的,那么main()中+的a,b的值也跟着改变。
//相比于传地址,在函数fun()中不用那么多的取值*操作,在传参过程中,主函数调用时不用&操作。

2.C++vector简介
题解:

//set方法可以使,插入的元素不重复,因此用set方法存密码串(cipher)是最方便的
class Solution {
public:
    int uniqueMorseRepresentations(vector<string>& words) {
        set<string> result;
        vector<string> cipher={".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.."};
        for(int i=0;i<words.size();i++)
        {
            string s="";
            for(int j=0;j<words[i].length();j++)
            {
                s+=cipher[words[i][j]-'a'];
            }
            result.insert(s);
        }
        return result.size();
    }
};
  1. 翻转图像
    容器vector reverse函数的应用
class Solution {
public:
vector<vector<int>> flipAndInvertImage(vector<vector<int>>& A) {
for(int i=0;i<A.size();i++)
{
reverse(A[i].begin(),A[i].end());
}
for(int i=0;i<A.size();i++)
for(int j=0;j<A[i].size();j++)
{
A[i][j]=!A[i][j];
}
return A;
}
};
  1. 汉明距离
class Solution {
public:
int hammingDistance(int x, int y) {
int res = x ^ y; //异或,运算规则:0^0=0;0^1=1;1^0=1;1^1=0;
int count = 0;
while(res!=0)
{
if(res & 1 == 1) //1的最低为是1其他位为0,相与可判断res最低位
count++;
res = res>>1;
}
return count;
}
};
  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* invertTree(TreeNode* root) {
        if(root==NULL)
            return NULL;
        TreeNode* tmp;
        tmp = root->left;
        root->left = root->right;
        root->right = tmp;
        invertTree(root->left);
        invertTree(root->right);
        return root;
    }
};
TreeNode* invertTree(TreeNode* root) { 	//后序遍历
      if(root==NULL) return root;
      invertTree(root->left);
      invertTree(root->right);
      TreeNode* temp = root->left;
      root->left = root->right;
      root->right = temp;
      return root;
 }
TreeNode* invertTree(TreeNode* root) {	//中序遍历
      if(root==NULL) return root;
      invertTree(root->left);
      TreeNode* temp = root->left;
      root->left = root->right;
      root->right = temp;
      invertTree(root->left);
      return root;
 }
  1. 机器人能否返回原点
class Solution {
public:
    bool judgeCircle(string moves) {
        int UD=0,LR=0;
        for(int i=0;i<moves.size();i++)
        {
            switch(moves[i])
            {
                case 'U':UD++;break;
                case 'D':UD--;break;
                case 'L':LR++;break;
                case 'R':LR--;break;
            }   
        }
       return (!UD && !LR); //都为0的话为1,否则为0;
    }
};
  1. 高度检查器
    桶排序简单应用:
class Solution {
public:
    int heightChecker(vector<int>& heights) {
        int bucket[101] = {0};  //桶初始化
        int result = 0;
        for(int i=0;i<heights.size();i++)
        {
            bucket[heights[i]]++;   //桶计数
        }
        for(int i=1,j=0;i<=100;i++) //分别用i和j遍历桶和输入数组
        {
            while(bucket[i]!=0)     //一个个从桶中取数据观察与heights中对应位置高度是否相等,若不相等,进行计数
            {
                if(i!=heights[j])
                {
                    result++;
                }
                j++;bucket[i]--;    //每从桶中取出一个数据,桶少一个元素,heights数组遍历下一个元素
            }
        }
        return result;
    }
};
  1. 二叉树的最大深度
    不知道自己写的问什么输入[1,2]输出是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 maxdepth = 0;
    int maxDepth(TreeNode* root) {
        dfs(root,1);
        return maxdepth;
    }
    void dfs(TreeNode* root,int depth)
    {
        if(root==NULL)
            return;
        if(root->left==NULL && root->right==NULL)
        {
            if(depth>maxdepth)
            maxdepth = depth;
        }    
        else if(root->left == NULL)
            dfs(root->right,depth++);
        else if(root->right == NULL)
            dfs(root->left,depth++);
        else
        {
            depth++;
            dfs(root->right,depth);
            dfs(root->left,depth);
        }
            
    }
};

精简版递归实现:

int maxDepth(TreeNode* root) {
    if(!root)return 0;	//空节点的return 0相当于深度初始化
        int L = maxDepth(root->left);
        int R = maxDepth(root->right);
        return L>R?L+1:R+1;	//回退一层深度+1
};

自己写的长的原因是不愿意进入一个NULL节点,而进行多次判断,其实进入NULL再进行判断反而要简单一点。虽然多进了一些节点,但是代码简洁了不少。

  1. 有序数组的平方
    快速排序讲解
    各个终止条件需要仔细斟酌。
class Solution {
public:
    vector<int> sortedSquares(vector<int>& A) {
        for(int i=0;i<A.size();i++)
        {
            A[i]=pow(A[i],2);
        }
        int low=0,high=A.size();
        quicksort(A,low,high-1);
        return A;
    }
    void quicksort(vector<int>& A,int low,int high)
    {
        if(low>high)return;
        int begin=low;
        int end=high;
        int tmp = A[low]; 
        while(low!=high)
        {
            while(A[high]=>tmp && low<high)high--; //这里的lowtmp只要判定的数字不小于都要让high--
            if(A[high]<tmp)
                A[low]=A[high];
            while(A[low]<=tmp && low<high)low++;
            if(A[low]>tmp)
                A[high]=A[low];
        }
        A[low]=tmp;
        quicksort(A,begin,low-1);
        quicksort(A,low+1,end);
    }
};
  1. 增减字符串匹配
class Solution {
public:
    vector<int> diStringMatch(string S) {
        int low=0,high=S.length();  
        vector<int> result;
        for(int i=0;i<S.length();i++)
        {
            if(S[i]=='I')
                result.push_back(low++);
            else
                result.push_back(high--);
        }
        result.push_back(low);
        return result;
    }
};
  1. 自除数
    容易忽略考虑个位为0的情况
class Solution {
public:
    vector<int> selfDividingNumbers(int left, int right) {
        vector<int> result;
        for(int i=left;i<=right;i++)
        {
            int tmp = i;
            while(tmp!=0)
            {
                if(tmp%10==0)break;
                if(i%(tmp%10)!=0)break;
                tmp=tmp/10;
            }
            if(tmp==0)
                result.push_back(i);
        }
        return result;
    }
};
  1. N叉树的后序遍历
/*
// Definition for a Node.
class Node {
public:
    int val;
    vector children;

    Node() {}

    Node(int _val, vector _children) {
        val = _val;
        children = _children;
    }
};
*/
class Solution {
public:
    vector<int> result;
    vector<int> postorder(Node* root) {
        if(root)
        {
            for(int i=0;i<root->children.size();i++)
            {
                postorder(root->children[i]);
            }
            result.push_back(root->val);
        }
         return result;
    }
};
  1. N叉树的前序遍历
class Solution {
public:
    vector<int> result;
    vector<int> preorder(Node* root) {
        if(root)
        {
            result.push_back(root->val);
            for(int i=0;i<root->children.size();i++)
            {
                preorder(root->children[i]);
            }
        }
        return result;
    }
};

非递归算法(调用栈):

//因为要保证左边的节点先被读出,因此入栈顺序要从右往左进行
//相对于递归来说内存消耗低,执行时间短
class Solution {
public:
    vector<int> result;
    stack<Node*> Stack;
    Node* top;
    vector<int> preorder(Node* root) {
        if(root)
        {
            Stack.push(root);
        }
        while(!Stack.empty())
        {
            top = Stack.top();
            Stack.pop();
            result.push_back(top->val);
            for(int i=top->children.size()-1;i>=0;i--)
            {
                Stack.push(top->children[i]);
            }
        } 
        return result;
    }
};
  1. 二叉搜索树中的搜索
class Solution {
public:
    TreeNode* searchBST(TreeNode* root, int val) {
        TreeNode* left,*right;
        if(!root)return NULL;
        else if(root->val==val)
            return root;
        else
        {
            left=searchBST(root->left,val);
            right=searchBST(root->right,val);
            return left?left:right;
        }
        
    }
};
  1. 除数博弈
    动态规划(递归做法,不适宜大数字,从大到小进行递归)
    记dp[N]为黑板上数字为N的情况下,Alice的输赢情况, 如果Alice取了数字x, 那么显然
    dp[N]与dp[N -x]输赢情况相反。x可以取的值很多,只要dp[N -xi]中任意一个为False, 那么dp[N]肯定为True, 否则dp[N]肯定为False
class Solution {
public:
    bool divisorGame(int N) {
        bool result;
        if(N==1)return false;
        else if(N==2)return true;
        else
        {
            for(int x=1;x<N;x++)
            {
                if(N%x==0)
                {
                    result = divisorGame(N-x);	//下一步的结果
                    if(result==false)	//下一步只要有一个是false,即鲍勃有一种可能是false,Alice则一定能赢
                        return true;
                }
            }
            return false;
        }
    }
};

动态规划非递归方法:
从小往大填数字

class Solution {
public:
    bool divisorGame(int N) {
        vector<bool> result(N+1,false);
        result[2]=true;
        for(int i=4;i<=N;i++)
        {
            for(int j=1;j<i;j++)
            {
                if(i%j==0 && result[i-j]==false)
                    result[i]=true;
            }
        }
        return result[N];
    }
};

476.数字的补数
换底公式(如下)加按位异或操作
c++log函数默认以10为底数
在这里插入图片描述

class Solution {
public:
    int findComplement(int num) {
        int tmp = (int)(log(num)/log(2))+1; 
        tmp=pow(2,tmp)-1; //得到一个和num位数一样的全一数
        return num^tmp;
    }
};
  1. 反转字符串中的单词 III
    字符异或交换法:
    a,b为两个字符
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
    则a,b交换,原理于此
class Solution {
public:
    string reverseWords(string s) {
        int begin=0,end;
        for(end=0;end<s.length();end++)
        {
            if(s[end]==' ')     //按照空格分隔字符串
            {
                reverse(begin,end-1,s);
                begin = end+1;
                end++;
            }
        }
        reverse(begin,end-1,s);     //最后一个单词不以空格结尾,需要单独再处理一次
        return s;
    }
    void reverse(int begin,int end,string &s)
    {
        while(begin<end)        //字符串异或交换法
        {
            s[begin]=s[begin]^s[end];
            s[end]=s[begin]^s[end];
            s[begin]=s[begin]^s[end];
            begin++;end--;
        }
    }
};
  1. 数组拆分 I
    快速排序应用
class Solution {
public:
    int arrayPairSum(vector<int>& nums) {
        int result=0;
        quicksort(0,nums.size()-1,nums);
        for(int i=0;i<nums.size();i=i+2)
            result+=nums[i];
        return result;
    }
    void quicksort(int i,int j,vector<int>& a)
    {   
        if(i>=j)return;
        int tmp=a[i];
        int begin=i;
        int end=j;
        while(i!=j)
        {
            while(a[j]>=tmp && i<j)j--;
            if(a[j]<tmp)a[i]=a[j];
            while(a[i]<=tmp && i<j)i++;
            if(a[i]>tmp)a[j]=a[i];
        }
        a[i]=tmp;
        quicksort(begin,i-1,a);
        quicksort(i+1,end,a);
    }
};
  1. 键盘行
    注意转换字符大小写函数toupper、tolower的使用
class Solution {
public:
    vector<string> findWords(vector<string>& words) {
        set<char> dic1 = {'Q','W','E','R','T','Y','U','I','O','P'};
        set<char> dic2 = {'A','S','D','F','G','H','J','K','L'};
        set<char> dic3 = {'Z','X','C','V','B','N','M'};
        vector<string> result;
        for(int i=0;i<words.size();i++)
        {
            int line1=0,line2=0,line3=0;
            for(int j=0;j<words[i].length();j++)
            {
                if(dic1.count(toupper(words[i][j])))line1++;
                if(dic2.count(toupper(words[i][j])))line2++;
                if(dic3.count(toupper(words[i][j])))line3++;
            }
            if(line1==words[i].length()||line2==words[i].length()||line3==words[i].length())
            {
                result.push_back(words[i]);
            }
        }
        return result;
    }
};
  1. 将有序数组转换为二叉搜索树
    如果做了 98 题 和 99 题,那么又看到这里的升序数组,然后应该会想到一个点,二叉搜索树的中序遍历刚好可以输出一个升序数组。
    所以题目给出的升序数组就是二叉搜索树的中序遍历。
    根据中序遍历还原一颗树,又想到了 105 题 和 106 题,通过中序遍历加前序遍历或者中序遍历加后序遍历来还原一棵树。前序(后序)遍历的作用呢?提供根节点!然后根据根节点,就可以递归的生成左右子树。
    这里的话怎么知道根节点呢?平衡二叉树,既然要做到平衡,我们只要把根节点选为数组的中点即可。
    综上,和之前一样,找到了根节点,然后把数组一分为二,进入递归即可。注意这里的边界情况,包括左边界,不包括右边界。
class Solution {
public:
    TreeNode* sortedArrayToBST(vector<int>& nums) {
        return devide(0,nums.size()-1,nums);
    }
    TreeNode* devide(int begin,int end,vector<int>& nums)	
    {
        if(begin>end)return NULL;    //递归结束条件
        int mid_pos=(begin+end)/2;  //二分法找到中间节点作为根节点
        TreeNode *node = new TreeNode(nums[mid_pos]);   //创建当前根节点
        node->left = devide(begin,mid_pos-1,nums);  //左子树递归构建
        node->right = devide(mid_pos+1,end,nums);    //右子树递归构建
        return node;
    }
};
  1. 删列造序
    字符串s删除第i个字符可用s.erase(i);此题目并没有要求,只要求计数。
class Solution {
public:
    int minDeletionSize(vector<string>& A) {
        int count=0;
        for(int i=0;i<A[0].length();i++)    //按列循环
        {
            for(int j=0;j+1<A.size();j++)   //按行循环
            {
                if(A[j][i]>A[j+1][i])      //检查到降序
                {
                    count++;    //删除操作+1
                    break;      //开始下一列循环
                }
            }
        }
        return count;
    }
};
  1. N叉树的最大深度
class Solution {
public:
    int maxDepth(Node* root) {
        if(!root)return 0;
        int max = 0;
        for(int i=0;i<root->children.size();i++)	//遍历每个子树
        {
            int deep=maxDepth(root->children[i]);
            if(deep>max)	//记录子树最大深度
            {
                max=deep;
            }
        }
        return max+1;	//返回子树最大深度+自身层(1层)
    }
};
  1. 最小差值 I
class Solution {
public:
    int smallestRangeI(vector<int>& A, int K) {
        int min=10000,max=0;
        for(int i=0;i<A.size();i++)
        {
            if(A[i]>max)max=A[i];
            if(A[i]<min)min=A[i];
        }
        if(max-min>2*K)
            return (max-min-2*K);
        else
            return 0;
    }
};
  1. 两个数组的交集
    迭代器使用重点掌握
class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        set<int> s;
        set<int> set_result;
        vector<int> vector_result;
        for(int i=0;i<nums1.size();i++) //将数组1所有元素压入set中,这样可去除重复元素
        {
            s.insert(nums1[i]);
        }
        for(int i=0;i<nums2.size();i++) //在set中找寻数组2中出现的元素压入结果set中
        {
            if(s.find(nums2[i])!=s.end())
            {
                set_result.insert(nums2[i]);
            }
        }
        for(set<int>::iterator iter=set_result.begin();iter!=set_result.end();iter++)//遍历结果set压入结果vector中
        {
            vector_result.push_back(*iter);
        }
        return vector_result;   //返回结果vector
    }
};
  1. 重复 N 次的元素
    C++ map用法总结(整理)
class Solution {
public:
    int repeatedNTimes(vector<int>& A) {
        set<int> s;
        for(int i=0;i<A.size();i++)
        {
            if(s.find(A[i])!=s.end())
                return A[i];
            else
                s.insert(A[i]);
        }
        return -1;
    }
};
  1. 转置矩阵
    二维数组(vector)初始化问题
class Solution {
public:
    vector<vector<int>> transpose(vector<vector<int>>& A) {
        vector<vector<int>> B(A[0].size(),vector<int>(A.size()));	//创建一个A[0].size()行,A.size()列的二维数组
        for(int i=0;i<A[0].size();i++)
        {
            for(int j=0;j<A.size();j++)
            {
                B[i][j]=A[j][i];
            }
        }
        return B;
    }
};
  1. 单值二叉树
    这题还把我难住了
class Solution {
public:
    bool isUnivalTree(TreeNode* root) {
        return judge(root,root->val);
    }
    bool judge(TreeNode* root,int val)
    {
        if(!root)       //主要是判断顺序的问题
            return true;
        bool left=judge(root->left,val);    //暂存左右子树的结果以便最后进行判断
        bool right=judge(root->right,val);
        if(root->val!=val)  //因为当前节点符合单值条件不能保证全部符合单值,因此不返回true
            return false;   //只要有一个不符合就返回flase
        return left && right;
            
    }
};
  1. 斐波那契数
class Solution {
public:
    int fib(int N) {
        if(N==0)return 0;
        else if(N==1)return 1;
        else return fib(N-1)+fib(N-2);
    }
};
  1. 按奇偶排序数组 II
    新创一个数组,如果是偶数放进偶数索引,如果是奇数放进奇数索引
class Solution {
public:
    vector<int> sortArrayByParityII(vector<int>& A) {
        vector<int>B(A.size());
        int odd=1,even=0;
        for(int i=0;i<A.size();i++)
        {
            if(A[i]%2==0)
            {
                B[even]=A[i];
                even+=2;
            }
            else
            {
                B[odd]=A[i];
                odd+=2;
            }
        }
        return B;
    }
};
  1. Excel表列序号
class Solution {
public:
    int titleToNumber(string s) {
        int result=0;
        for(int i=s.length()-1;i>=0;i--)
        {
            result+=(s[i]-'A'+1)*pow(26,s.length()-1-i);
        }
        return result;
    }
};
  1. 车的可用捕获量
class Solution {
public:
    int numRookCaptures(vector<vector<char>>& board) {
        int flag=0;
        int row,col;
        int count=0;
        for(int i=0;i<board.size();i++)
        {
            for(int j=0;j<board[i].size();j++)
            {
                if(board[i][j]=='R')
                {
                    row=i;
                    col=j;
                    flag=1;
                    break;
                }
            }
            if(flag==1)break;
        }
        for(int i=row-1;i>=0;i--)
        {
            if(board[i][col]=='B')break;
            if(board[i][col]=='p'){count++;break;}
        }
        for(int i=row+1;i<board.size();i++)
        {
            if(board[i][col]=='B')break;
            if(board[i][col]=='p'){count++;break;}
        }
        for(int i=col-1;i>=0;i--)
        {
            if(board[row][i]=='B')break;
            if(board[row][i]=='p'){count++;break;}
        }
        for(int i=col+1;i<board[row].size();i++)
        {
            if(board[row][i]=='B')break;
            if(board[row][i]=='p'){count++;break;}
        }
        return count;
    }
};

206.反转链表
头插法思路:此题可以采取头插法,首先创建一个无意义头结点,然后把整个链表采用头查法的方式来重新插入整个链表,因为每次插入都是插在头部,就慢慢的把前面插入的数往后面挤了。

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *p = new ListNode(-1);	//新链表头节点
        p->next=NULL;
        ListNode *t=head;
        ListNode *s;
        while(t!=NULL)
        {
            s=t;	//s作为当前插到新链表的节点
            t=t->next;	//t依次向后移动
            s->next=p->next;	//插入新链表p
            p->next=s;	//插入新链表p
        }
        return p->next;	//p节点没有意义,p->next作为头节点
    }
};

玄学递归法
Leetcode学习过程(持续更新)_第3张图片

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(head==NULL||head->next==NULL)
            return head;
        ListNode *p = reverseList(head->next);
        head->next->next=head;
        head->next=NULL;
        return p;
    }
};
  1. 棒球比赛
    关于vector.erase的用法
class Solution {
public:
    int calPoints(vector<string>& ops) {
        int result=0;
        for(int i=0;i<ops.size();i++)
        {
            if(ops[i]=="C")		//如果碰到c就删除C和之前的两个vector
            {
                ops.erase(ops.begin()+i-1,ops.begin()+i+1);
                i=i-2;	//因为删除了两个,所以下次遍历的数字索引要减2
            }
        }
        for(int i=0;i<ops.size();i++)
        {
            if(ops[i]=="D")
                ops[i]=to_string(stoi(ops[i-1])*2);	//stoi将字符串数字转换为字符串
            else if(ops[i]=="+")
                ops[i]=to_string(stoi(ops[i-1])+stoi(ops[i-2]));	//to_string将数字转换成字符串
        }
        for(int i=0;i<ops.size();i++)
        {
            result+=stoi(ops[i]);
        }
        return result;
    }
};
  1. 子域名访问计数
class Solution {
public:
    vector<string> subdomainVisits(vector<string>& cpdomains) {
        map<string,int> M;  //存放域名对应数量
        vector<string> result;  //存放结果
        for(auto str:cpdomains) //自动变量循环vector
        {
            int num;    
            string str1,str2,str3;
            istringstream sstr(str);	//转换为字符串输入流sstr
            sstr>>num>>str1; //字符输出流,按照空格或TAB分隔,神奇的是num竟然可以直接保存为数字,而不是“9001”串
            M[str1]+=num;   //字典直接插入str1,并加上value值
            str2=str1.substr(str1.find('.')+1); //find函数从左往右遍历到第一个‘.’返回索引
            M[str2]+=num;
            if(str2.find('.')!=str2.npos)   //字符串遍历没找到返回string.npos
            {
                str3=str2.substr(str2.find('.')+1);
                M[str3]+=num;
            }
        }
        for(auto a:M)   //自动变量循环map
        {
            result.push_back(to_string(a.second)+' '+a.first);  //给结果vector添加值
        }
        return result;
    }
};
  1. 独特的电子邮件地址
class Solution {
public:
    int numUniqueEmails(vector<string>& emails) {
        set<string> result;
        for(auto str:emails)
        {
            string local,area;  //本地名,域名
            area=str.substr(str.find('@')+1);	//substr第一个参数为起始位置,第二个参数为长度
            local=str.substr(0,str.find('@'));	//一定要记得加“local=”才行,返回值才是裁剪好的子串,
            if(local.find('+')!=local.npos)
                local=local.substr(0,local.find('+'));
            
            for(string::iterator iter=local.begin();iter!=local.end();iter++)	//删除特定字符就用迭代器吧
            {
                if(*iter=='.')
                    local.erase(iter);
            }
            result.insert(local+'@'+area);
        }
        return result.size();
    }
};

你可能感兴趣的:(Leetcode学习过程(持续更新))