刷不动的leetcode系列(三)

159 阅读5分钟

41.给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。

示例 1:

输入: [1,2,3,4,5,6,7] 和 k = 3 输出: [5,6,7,1,2,3,4] 解释: 向右旋转 1 步: [7,1,2,3,4,5,6] 向右旋转 2 步: [6,7,1,2,3,4,5] 向右旋转 3 步: [5,6,7,1,2,3,4]

class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        // 三次翻转搞定
        k = k % nums.size();
        reverse(nums.begin(), nums.begin() + nums.size() - k);
        reverse(nums.begin() + nums.size() - k, nums.end());
        reverse(nums.begin(), nums.end());
    }
};

42.颠倒给定的 32 位无符号整数的二进制位。

class Solution {
public:
    uint32_t reverseBits(uint32_t n) {
        uint32_t res=0;
        for(int i=0;i<32;i++)
        {
            res<<=1;
            res+=n&1;
            n>>=1;
        }
        return res;
        
    }
};

编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。

示例 1:

输入:00000000000000000000000000001011 输出:3 解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。

int hammingWeight(uint32_t n) {
        int res=0;
        while(n)
        {
            res+=n%2;
            n>>=1;
        }
        return ans;
    }

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int res=0;
        for(int i=0;i<32;i++)
        {
            res+=n&1;
            n>>=1;
        }
        return res;
    }
};

44.你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。

示例 1:

输入: [1,2,3,1] 输出: 4 解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。 偷窃到的最高金额 = 1 + 3 = 4 。

class Solution {
public:
    int rob(vector<int>& nums) {
        if(nums.size()==0)
            return 0;
        if(nums.size()==1)
            return nums[0];
        if(nums.size()<3)
            return max(nums[0],nums[1]);
        vector<int> dp(nums.size());
        dp[0]=nums[0];
        dp[1]=max(nums[0],nums[1]);
        int res=0;
        for(int i=2;i<nums.size();i++)
        {
            dp[i]=max(dp[i-2]+nums[i],dp[i-1]);
            if(res<dp[i])
                res=dp[i];
        }
        return res;
    }
    
};

45.编写一个算法来判断一个数是不是“快乐数”。

一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数。

示例:

输入: 19 输出: true 解释: 12 + 92 = 82 82 + 22 = 68 62 + 82 = 100 12 + 02 + 02 = 1

class Solution {
public:
    bool isHappy(int n) {
        int res=0;
        while(n)
        {
            res=res+pow(n%10,2);
            n/=10;
            cout<<res<<endl;
        }
        if(res==1)
            return true;
        else if(res==4)
            return false;
        return isHappy(res);
    }
};

46.删除链表中等于给定值 val 的所有节点。

示例:

输入: 1->2->6->3->4->5->6, val = 6 输出: 1->2->3->4->5

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* res=new ListNode(-1);
        res->next=head;//头节点来简便运算
        ListNode* p=res;
        while(p->next)
        {
            if(p->next->val==val)
                p->next=p->next->next;
            else
                p=p->next;
        }
        return res->next;
        
    }
};

47.统计所有小于非负整数 n 的质数的数量。

示例:

输入: 10 输出: 4 解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。

//厄拉多塞筛法. 比如说求20以内质数的个数,首先0,1不是质数.2是第一个质数,然后把20以内所有2的倍数划去.2后面紧跟的数即为下一个质数3,然后把3所有的倍数划去.3后面紧跟的数即为下一个质数5,再把5所有的倍数划去.以此类推.
class Solution {
public:
    int countPrimes(int n)
    {
        int a[n+1]; 
        int count = 0;
        for(int i = 2; i < n; i++)
            a[i] = 1;
    
        for(int i = 2; i < n; i++)
          if(a[i])
        {
            count++;
            for(int j = 2 * i; j < n; j += i)
                a[j] = 0;
        }
        return count;
    }
};

48.给定两个字符串 s 和 t,判断它们是否是同构的。

如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。

所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。

示例 1:

输入: s = "egg", t = "add" 输出: true

示例 2:

输入: s = "foo", t = "bar" 输出: false

示例 3:

输入: s = "paper", t = "title" 输出: true

//重点,必须一一对应,所以,要用两个类似的字典相互
class Solution {
public:
    bool isIsomorphic(string s, string t) {
        if(s.size()!=t.size())
            return false;
        int take[256]={};
        int back[256]={};
        for(int i=0;i<s.size();i++)
        {
            if(!take[s[i]]&&!back[t[i]])
            {   
                take[s[i]]=t[i];
                back[t[i]]=s[i];
            }
            if(take[s[i]]!=t[i]||back[t[i]]!=s[i])
                return false;
        }
        return true;       
    }
};

49.反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL

进阶: 你可以迭代或递归地反转链表。你能否用两种方法解决这道题?

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *res=new ListNode(-1);
        ListNode *p;
        while(head)
        {
            p=head->next;
            head->next=res->next;
            res->next=head;
            head=p;
        }
        return res->next;
        
    }
};
//第二种迭代,某个秀得不行的大佬写的。。。

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *p;
        for(p=NULL; head; swap(head,p))
            swap(p,head->next);
        return p;
    }
};

50.给定一个整数数组,判断是否存在重复元素。

如果任何值在数组中出现至少两次,函数返回 true。如果数组中每个元素都不相同,则返回 false。

示例 1:

输入: [1,2,3,1] 输出: true

示例 2:

输入: [1,2,3,4] 输出: false

class Solution {
public:
    bool containsDuplicate(vector<int>& nums) {
        set<int> s;
        for(int i=0;i<nums.size();i++)
        {
            if(s.find(nums[i])!=s.end())
                return true;
            s.insert(nums[i]);
        }
        return false;
    }
};