leetcode解题思路分析(三十四)242—264题

  1. 有效的字母异位词
    给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

本题采用哈希表或者排序易解

class Solution {
public:
    bool isAnagram(string s, string t) {
        if(s.size() != t.size())
            return false;
            
        int hash[26]={0};       //构建哈希数组
        for(auto n:s)
            hash[n-'a']++;
        for(auto n:t)
            hash[n-'a']--;
        for(int i=0;i<26;i++)
            if(hash[i]!=0)   return false;          //如果两数组不完全相等
        return true;
    }
};


  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 {
    vector<string> ret;
public:
    vector<string> binaryTreePaths(TreeNode* root) {
        if (root == NULL) return ret;
        string str = to_string(root->val);
        PrintPath(str, root);
        return ret;
    }

    void PrintPath(string str, TreeNode *node)
    {
        if (node == NULL || (node->left == NULL && node->right == NULL)) 
        {
            ret.push_back(str);    
            return;
        }
        
        if (node->left != NULL)
        {
            string s = str + "->" + to_string(node->left->val);
            PrintPath(s, node->left);
        }
        if (node->right != NULL)
        {
            str += "->" + to_string(node->right->val);
            PrintPath(str, node->right);           
        }     
    }
};
  1. 各位相加
    给定一个非负整数 num,反复将各个位上的数字相加,直到结果为一位数。

最简单的方法就是不停迭代直接求解。更好的做法是利用abcd = 1000 * a + 100 * b + 10 *c + d = 999 * a + 99 * b + 9 *c + a + b + c + d,直接对9取余即可

class Solution {
public:
    int addDigits(int num) {
        while (num > 9)
        {
            int ret = 0;
            while (num > 0)
            {
                ret += num % 10;
                num = num / 10;
            }
            num = ret;
        }

        return num;

    }
};
class Solution {
public:
    int addDigits(int num) {
        while (num > 9)
        {
            num = (num - 1) % 9 + 1;
        }
        return num;
    }
};
  1. 只出现一次的数字
    给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。

本题可用排序、哈希表解决,但是最优解法为位操作。这里核心思想在于通过异或,相同元素可以除去。通过补码和原码的与操作,我们可以得到两个元素最低不相同的位,以此为判断原则遍历区分

class Solution {
public:
vector<int> singleNumber(vector<int>& nums) 
{
    int sign = 0;
    //取得数组中两个唯一数的按位异或结果
    for (int i = 0; i < nums.size(); i++)
    {
        sign ^= nums[i];
    }
    //获取区分两个唯一数的比特位所代表的值
    //也可以写成:sign &= (~sign) + 1
    sign &= -sign;
    int n1 = 0, n2 = 0;
    //通过标识,区分两个数组
    for (int i = 0; i < nums.size(); i++)
    {
        if ((nums[i] & sign) == sign)
            n1 ^= nums[i];
        else
            n2 ^= nums[i]; ;
    }
    return { n1,n2 };
}
};
  1. 行程和用户
    写一段 SQL 语句查出 2013年10月1日 至 2013年10月3日 期间非禁止用户的取消率。

对trips表和users表连接,连接条件是行程对应的乘客非禁止且司机非禁止
筛选订单日期在目标日期之间
用日期进行分组
分别统计所有订单数和被取消的订单数,其中取消订单数用一个bool条件来得到0或1,再用avg求均值
对订单取消率保留两位小数,对输出列名改名

# Write your MySQL query statement below
SELECT
    request_at as 'Day', round(avg(Status!='completed'), 2) as 'Cancellation Rate'
FROM 
    trips t JOIN users u1 ON (t.client_id = u1.users_id AND u1.banned = 'No')
    JOIN users u2 ON (t.driver_id = u2.users_id AND u2.banned = 'No')
WHERE	
    request_at BETWEEN '2013-10-01' AND '2013-10-03'
GROUP BY 
    request_at


  1. 丑数
    编写一个程序判断给定的数是否为丑数。
    丑数就是只包含质因数 2, 3, 5 的正整数。

循环除就好

class Solution {
public:
    bool isUgly(int num) {

        if (num == 0) return false;
        
        set<int> ugly = {2, 3, 5};

        for (auto div : ugly)
        {
            while (num % div == 0)
            {
                num = num / div;               
            }
        }

        if (num == 1) 
            return true;
        else
            return false;
    }
};
  1. 丑数2
    编写一个程序,找出第 n 个丑数。
    丑数就是质因数只包含 2, 3, 5 的正整数。

本题采用动态规划求解,需要三个指针指向上一个乘过的数,然后每次取3个数中的最小数,接着指针移动。注意本题的动态规划不适合降维:因为依赖项多

class Solution {
public:
    int nthUglyNumber(int n) {
        vector<int> dp(n, 0);
        dp[0] = 1;
        int p2 = 0, p3 = 0, p5 = 0;
        for(int i = 1; i < n; i ++){
            dp[i] = min(min(dp[p2] * 2, dp[p3] * 3), dp[p5] * 5);
            if(dp[i] == dp[p2]*2) p2++;
            if(dp[i] == dp[p3]*3) p3++;
            if(dp[i] == dp[p5]*5) p5++;
        }
        return dp[n - 1];
    }
};

你可能感兴趣的:(面试,补码,算法,leetcode,数据结构)