Leetcode个人记录(一)

记录每天做过的leetcode题目,哈哈哈,和灰一起努力的日子~

  • 189旋转数组
class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        if(k>nums.size())
        k=k%nums.size();
        //reverse(nums,0,nums.size()-1);
        //reverse(nums,0,k-1);
        //reverse(nums,k,nums.size()-1);
        reverse(nums.begin(),nums.end());
        reverse(nums.begin(),nums.begin()+k);
        reverse(nums.begin()+k,nums.end());

    }
    /*void reverse(vector<int>& arr,int s,int e)
    {
        int n;
        while(s<e)
        {
            n=arr[e];
            arr[e]=arr[s];
            arr[s]=n;
            ++s;
            --e;
        }
    }*/
};

reverse函数的使用方法;三次翻转的做法;k应该先取余。

  • 121买卖股票的最佳时机
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int ans=0;
        int i,j;
        if(prices.size()<=0) return 0;
        for(i=0;i<prices.size()-1;++i)
        {
            //if(prices[i]>prices[i+1])
            //{
                for(j=i+1;j<prices.size();++j)
                {
                    if(prices[j]-prices[i]>ans)
                    ans=prices[j]-prices[i];
                }
           // }
           if(prices[i]<prices[i+1])
           ++i;
        }
        return ans;
    }
};

注意输入为0的情况。

  • 543二叉树的直径
class Solution {
    int ans;
    int depth(TreeNode* rt) {
        if(rt==NULL) return 0;
        int L=depth(rt->left);
        int R=depth(rt->right);
        ans=max(ans,L+R);
        return max(L,R)+1;
    }

public:
    int diameterOfBinaryTree(TreeNode* root) {
        ans=0;
        depth(root);
        return ans;
    }
};

注意直径有可能不经过根。

  • 1013将数组分成和相等的三个部分
class Solution {
public:
    bool canThreePartsEqualSum(vector<int>& A) {
        int i=0,j=0;
        int sum=0;
        int yushu=32766;
        int sum1=0;
        int sum2=0;
        int sum3=0;
        int sumDividedBy3=0;
        for(i=0;i<A.size();++i) {
            sum=sum+A[i];
        }
        sumDividedBy3=sum/3;
        yushu=sum%3;
        if(yushu!=0) return false;
        for(i=0;i<A.size()-2;++i) {
            sum1=sum1+A[i];
            if(sumDividedBy3 == sum1)
            break;
        }
        for(j=i+1;j<A.size()-1;++j) {
            sum2=sum2+A[j];
            if(sumDividedBy3 == sum2)
            break;
        }
        sum3=sum-sum1-sum2;
        if(sum1==sum2 && sum2==sum3)
        return true;
        else return false;


    }
};

这道题总是自测可以过,到机测总是过不了,找不到原因,灰帮我查出来是因为最开始的数都没有初始化,大概在不同的case测试时,初值就是上一次的结果,导致测试不对。

  • 202快乐数
class Solution {
public:
    bool isHappy(int n) {
        int count=0;
        int sum=0;
        while(count<10) {
            vector <int> digit;
            while(n>0){
                digit.push_back(n%10);
                n /= 10;
            }
            n=0;
            for(int i=0;i<digit.size();++i) {
                n += digit[i]*digit[i];
            }
            if(n==1) {
                return true;
            }
            ++count;
        }
        return false;

    }
};

这个方法肯定是不完善的,记录主要是为了记住如何把每一位数字分开存起来。
答案区有用快慢指针思想找出循环的!

  • 204计数质数
class Solution {
public:
    int countPrimes(int n) {
        int ans=0;
        int count=0;
        int i=0,j=0;
        if(n <= 2) return 0;
        else
        {
            ++ans;
            for(i=3;i<n;++i)
            {
                if(i%2 == 0) continue;
                for(j=1;j*j<=i;j+=2) {
                    if(i%j == 0) {
                        ++count;
                    }
                    if(count>1) break;
                }
                if(count == 1)
                    ++ans;
                count = 0;
            }
            return ans;
        }
    }
};

写的时候一直超时,最后还是灰帮我加了一句判断count>1才调通。答案的经典解法是厄拉多塞筛法。

  • 144二叉树的前序遍历
class Solution {
public:
    void preode(TreeNode* rt,vector<int> & ans) {
        if(rt==NULL) return;
        ans.push_back(rt->val);
        preode(rt->left,ans);
        preode(rt->right,ans);
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector <int> ans;
        preode(root,ans);
        return ans;
    }
};

记住代码怎么写,还有push_back和emplace_back的区别。

  • 111二叉树的最小深度
class Solution {
    int ans;
    int min_depth(TreeNode* rt) {
        if(rt==NULL) return 0;
        int L=min_depth(rt->left);
        int R=min_depth(rt->right);
        if(rt->left && rt->right) {//不空
            ans=min(L,R)+1;
            return ans;
        }
        else if(!rt->left || !rt->right) {//空一个
            return max(L,R)+1;
        }
        else//全空
            return 1;
    }
public:
    int minDepth(TreeNode* root) {
        ans=0;
        ans=min_depth(root);
        return ans;
    }
};

注意递归条件,而且没有必要再写一个函数。

  • 101对称二叉树
class Solution {
    bool isMirror(TreeNode* n1, TreeNode* n2) {
        if(n1 == nullptr && n2 == nullptr) return true;
        if(n1 == nullptr || n2 ==  nullptr) return false;
        if(n1->val != n2->val) return false;
        return isMirror(n1->left,n2->right) && isMirror(n1->right,n2->left);
    }
public:
    bool isSymmetric(TreeNode* root) {
        if(root == nullptr) return true;
        return isMirror(root->left,root->right);
    }
};

我自己的思路是中序遍历二叉树,然后将遍历结果转置,看转置以后的结果与原结果是否相等来判断,对于题干中出现的特殊情况,把NULL用一个特殊值来替代,例如32766,但是对于底下的这种特殊情况,仍不能解决。上述代码是题解。
特殊情况
因为即使是把NULL代替了,中序遍历结果也是
在这里插入图片描述

  • 217存在重复元素
class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        if(nums.size() == 0 || nums.size() == 1) return false;
        int i=0;
        //BubbleSort(nums);
        sort(nums.begin(),nums.end());
        for(i=0;i<nums.size()-1;++i) {
            if(nums[i] == nums[i+1])
                return true;
        }
        return false;
    }
    void BubbleSort(vector<int>& arr) {
        int i=0,j=0;
        int temp=0;
        int flag;
        for(i=0;i<arr.size()-1;++i)
        {
            flag=0;
            for(j=0;j<arr.size()-1-i;++j) {
                if(arr[j]>arr[j+1])
                {
                    temp=arr[j];
                    arr[j]=arr[j+1];
                    arr[j+1]=temp;
                    flag=1;
                }
            }
            if(flag==0)
            break;
        }
    }
};

其实冒泡排序的时间复杂度也是O(n^2),与两个for循环比对重复元素的时间复杂度一致,之所以能过是因为leetcode给的case都是有序数组,所以过了,看题解快排就超出了时间限制。灰让我去了解unordered_map()。

  • 219存在重复元素Ⅱ
class Solution {
public:
    bool containsNearbyDuplicate(vector<int>& nums, int k) {
        unordered_map <int,int> TraversedNums;
        int i=0;
        for(i=0;i<nums.size();++i) {
            auto iter=TraversedNums.find(nums[i]);
            if(iter != TraversedNums.end()) {
                if(i-iter->second <= k) return true;
                else iter->second = i;
            }
            else TraversedNums[nums[i]] = i;
        }
        return false;
        /*int i=0,j=0;
        if(nums.size() == 0 || nums.size() == 1) return false;
        if(nums.size() == 2 && nums[0] == nums[1] && k>0) return true;          
        int nums_size=nums.size();
        for(i=0;i<nums.size()-1;++i) {
                for(j=i+1;j<min(i+k+1,nums_size);++j) {
                    if(nums[i] == nums[j])
                        return true;
                }
        }
        return false;*/
    }
};

注释的方法超超时了,学习了昨天灰说的unordered_map,代码是照着一个题解写的,还不是很会用。
以下是灰给我的讲解。 TraversedNums[n]=xxx; 这种写法的话,无论这个map中是否已经存在以关键词n为键的数据,都会在map中更新一条 n->xxx的数据。

  • 409最长回文串
class Solution {
public:
    int longestPalindrome(string s) {
        unordered_map <char,int> TraversedStr;
        int ans=0;

        for(int n:s) 
            ++TraversedStr[n];

        for(auto iter : TraversedStr) {
            int count = iter.second;
            ans = ans + count / 2 * 2;
            if(count % 2 == 1 && ans % 2 == 0)
            ++ans;
        }

        return ans;
    }
};

这个是题解,因为题解很有学习的价值,所以存起来学习。

  • 40最小的k个数
class Solution {
        void quicksort(vector<int>& arr, int l, int r) {
        if(l < r) {
            int i=l,j=r;
            int x=arr[l];
            while(i < j) {
                while(i < j && arr[j] >= x)
                --j;
                if(i < j) {
                    arr[i] = arr[j];
                    ++i;
                }
                while(i < j && arr[i] <= x)
                ++i;
                if(i<j) {
                    arr[j] = arr[i];
                    --j;
                }
            }
            arr[i] = x;
        quicksort(arr,l,i-1);
        quicksort(arr,i+1,r);
        }
    }
public:
    vector<int> getLeastNumbers(vector<int>& arr, int k) {
        vector<int>  ans;
        int aSize=arr.size()-1;
        quicksort(arr,0,aSize);
        for(int i=0;i<k;++i) {
            ans.push_back(arr[i]);
        }
        return ans;
    }
};
  • 28实现strStr()
class Solution {
public:
    int strStr(string haystack, string needle) {
        if(needle.size() == 0) return 0;
        int i = 0;
        int j = 0;
        if(needle.size() > haystack.size()) return -1; 
        while(i < haystack.size()) {
            for(j = 0;j<needle.size();++j) {
                if(haystack[i+j] != needle[j]) {
                    break;
                }
            }
            if(j == needle.size())
                return i;
            ++i;
        }
        return -1;
    }
};
  • 220存在重复元素Ⅲ
class Solution {
public:
    bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
        if(t<0 || nums.size()==0 || k<1) return false;
        long long mod = t+1ll;
        unordered_map<long long,long long> buck;
        for(int i=0;i<nums.size();++i) {
            int nth = nums[i]/mod;
            if(nums[i] < 0) --nth;
            if(buck.find(nth) != buck.end())
                return true;
            if(buck.find(nth-1) != buck.end() && abs(nums[i]-buck[nth-1]) <=t)
                return true;
            if(buck.find(nth+1) != buck.end() && abs(nums[i]-buck[nth+1]) <=t)
                return true;
            buck[nth] = nums[i];
            if(i>=k)
                buck.erase(nums[i-k]/mod);
        }  
        return false;
    }
};

这个是题解排名第二的答案,看了很久才懂,记录主要是为了buck.erase这个函数,删除的是整个容器,key和value值,unordered_map对应的是<int,vector>时,删掉的也是整个vector。

  • 面试题17.16按摩师
class Solution {
public:
    int massage(vector<int>& nums) {
        if(nums.size() == 0) return 0;
        if(nums.size() == 1) return nums[0];
        if(nums.size() == 2) return max(nums[0],nums[1]);
        int i=0;
        vector<int> temp(nums.size(),0);//temp[i]存前i-1位数中的最长数
        temp[0]=nums[0];
        temp[1]=max(nums[0],nums[1]);
        for(i=2;i<nums.size();++i) {
            temp[i]=max(nums[i]+temp[i-2],temp[i-1]);
        }
        return temp[i-1];
    }
};
  • 213打家劫舍Ⅱ
class Solution {
public:
    int rob(vector<int>& nums) {
        if(nums.size() == 0) return 0;
        if(nums.size() == 1) return nums[0];
        if(nums.size() == 2) return max(nums[0],nums[1]);
        int count = nums.size();
        vector<int> cutone(count-1,0);//去掉第一个数的最大数
        vector<int> cutlast(count-1,0);//去掉第二个数的最大数
        cutone[0] = nums[1];
        cutone[1] = max(nums[2],nums[1]);
        cutlast[0] = nums[0];
        cutlast[1] = max(nums[0],nums[1]);
        for(int i=2;i<count-1;++i) {
            cutone[i] = max(nums[i+1]+cutone[i-2],cutone[i-1]);
            cutlast[i] = max(nums[i]+cutlast[i-2],cutlast[i-1]);
        }
        return max(cutone[count-2],cutlast[count-2]);
    }
};
  • 914卡牌分组
class Solution {
    int gcd(int a,int b) {
        return b==0?a:gcd(b,a%b);
    }
public:
    bool hasGroupsSizeX(vector<int>& deck) {
        if(deck.size() == 0) return false;
        int X = 0;
        unordered_map <int,int> sort_num;
        for(int it:deck) {
            ++sort_num[it];
        }
        for(auto iter : sort_num) {
            if(iter.second==1)
                return false;
            X=gcd(X,iter.second);
            if(X == 1)
            return false;
        }
        return true;
    }
};

参考答案的,注意unordered_map和gcd的写法。

  • 999可以被一步捕获的棋子数
class Solution {
public:
    int numRookCaptures(vector<vector<char>>& board) {
        int count=0;
        int i=0,j=0,flag=-1;
        int hang = board.size();
        int lie = board[i].size();
        for(i=0;i<hang;++i) {//find R
            for(j=0;j<lie;++j) {
                if(board[i][j] == 'R') {
                    flag=1;break;
                }       
            }
            if(flag == 1)
                break;
        }
        if(j > 0) {//遍历上
            for(int n=j-1;n>=0;--n) {
                if(board[i][n] == 'p') {
                    ++count;break;
                }  
                if(board[i][n] == 'B')
                    break;
            }
        }
        if(j < hang) {//遍历下
            for(int n=j+1;n<lie;++n) {
                if(board[i][n] == 'p') {
                    ++count;
                    break;
                }      
                if(board[i][n] == 'B')
                    break;
            }
        }
        if(i > 0) {//遍历左
            for(int n=i-1;n>=0;--n) {
                if(board[n][j] == 'p') {
                    ++count;break;
                }      
                if(board[n][j] == 'B')
                    break;
            }
        }
        if(i < hang) {//遍历下
            for(int n=i+1;n<lie;++n) {
                if(board[n][j] == 'p') {
                    ++count;break;
                }
                if(board[n][j] == 'B')
                    break;
            }
        }
        return count;
    }
};
  • 231 2的幂
class Solution {
public:
    bool isPowerOfTwo(int n) {
        if(n == 0) return false;
        if(n == 1) return true;
        int flag=0;
        while(n % 2 == 0) {
            n=n/2;
            if(n == 1){
                flag=1;
                break;
            }
        }
        if(flag==1)
            return true;
        else return false;

        /*if(n>0 && !(n&(n-1)))
        return true;
        else return false;*/

        //return n > 0 && !(n & (n - 1));
    }
};
  • 223矩形面积
class Solution {
public:
    int calculate_square(int a, int b, int c, int d) {
        return (c - a) * (d - b);
    }
    int computeArea(int A, int B, int C, int D, int E, int F, int G, int H) {
        int s1 = 0, s2 = 0;
        int x1 =0, y1 = 0, x2 = 0, y2 = 0;
        int s_rep = 0;
        int ans = 0;
        s1 = calculate_square(A, B, C, D);
        s2 = calculate_square(E, F, G, H);
        if(C <= E || F >= D || A >= G || B >= H)
            s_rep = 0;
        else {
            x1 = max(A,E);
            y1 = max(B,F);
            x2 = min(G,C);
            y2 = min(D,H);
            s_rep = calculate_square(x1, y1, x2, y2);
        }
        ans = s1 + (s2 - s_rep);
        return ans;
    }
};
  • 面试题62圆圈中最后剩下的数字
class Solution {
public:
    /*int ysf(int n,int m) {
        if(n == 1)
        return 0;
        else return (ysf(n-1,m) + m ) % n;
    }*/
    int lastRemaining(int n, int m) {
        int i;
        int ans = 0;
        for(i = 2;i<(n+1);++i) {
            ans = (ans + m) % i;
        }
        return ans;
        //return ysf(n,m);
    }
};

这个答案是抄的题解,实际约瑟夫环,返回的是被删掉的序号,可以考虑用erase来写,但是c++的erase是找到指定元素,删除,将后面的元素依次往前移,会超时,不过可以学习erase的写法。https://blog.csdn.net/weixin_41969587/article/details/82587372

  • 226翻转二叉树
/**
 * 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;
        invertTree(root->left);
        invertTree(root->right);
        //TreeNode* temp;
        //temp=root->right;
        //root->right=root->left;
        //root->left=temp;
        swap(root->left,root->right);
        return root;
    }
};

  • 205同构字符串
class Solution {
public:
    bool isIsomorphic(string s, string t) {
        unordered_map<char,char> szifu;
        unordered_map<char,char> tzifu;
        int s_count = 0;
        for(int i = 0;i < s.size();++i) {
            if(szifu.find(s[i]) != szifu.end()) {//if exist
                if(szifu[s[i]] != t[i])//如果不是原来的映射,会自动创建映射
                    break;
                else ++s_count;//如果是原来的映射
            }
            else {//如果不存在,创建并且判断与之前的字母有没有重合
                ++s_count;
                szifu[s[i]] = t[i];
            }
        }
        int t_count = 0;
        for(int i = 0;i < t.size();++i) {
            if(tzifu.find(t[i]) != tzifu.end()) {//if exist
                if(tzifu[t[i]] != s[i])//如果不是原来的映射,会自动创建映射
                    break;
                else ++t_count;//如果是原来的映射
            }
            else {//如果不存在,创建并且判断与之前的字母有没有重合
                ++t_count;
                tzifu[t[i]] = s[i];
            }
        }
        if(s_count == s.size() && t_count == t.size())
            return true;
        else return false;
        //这个是灰教的方法,就很机智,find()函数找出这个字母第一次出现的下标
        /*for(int i = 0;i < s.size(); ++i) {
            if(s.find(s[i]) != t.find(t[i]))
                return false;
        }
            return true;*/        
    }
};
  • 234回文链表
/**
 * 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) {
        //if(head == NULL) return true;
        vector<int> nums;
        while(head) {
            nums.push_back(head->val);
            head = head->next;
        }
        for(int i = 0;i<nums.size();++i) {
            if(nums[i] != nums[nums.size()-i-1])
            return false;
        }
        return true;
    }
};

记住返回true和false的方法,这样返回可以注释掉链表为空的情况。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值