[研究生冲刺][算法实习生]LeetCode刷题日记(Day2)
5479. 千位分隔数(第33场双周赛issue 1)
思路:
主要思路是每次用n对1000取余,然后将其加上一个 “.” 之后加到最终字符串的前面,然后用n/1000赋给n。要注意的是当n<1000时要将其直接转成字符串放到最终字符串的前面。用到的int to string 的函数为 to_string()。过程中要注意如果 temp <100 以及 temp < 10 时要做补0的处理。
算法的复杂度:
算法的时间复杂度为O(n/3) = O(n)。因为没有产生额外空间,所以算法的空间复杂度为O(1)。
代码:
class Solution {
public:
string thousandSeparator(int n) {
string res = "";
string point = ".";
string zero = "0";
while(n > 1000)
{
int temp = n % 1000;
string s = to_string(temp);
if(temp >= 100)
res = point + s + res;
else if(temp >= 10)
res = point + zero + s + res;
else if(temp >= 1)
res = point + zero + zero + s + res;
else
res = point + zero + zero + zero + res;
n = n / 1000;
}
res = to_string(n) + res;
return res;
}
};
5480. 可以到达所有点的最少点数目(第33场双周赛issue 2)
思路:
因为题目中说了这是一个DAG图(有向无环图),所以不存在环,因此我们可以通过反证法证明所有入度为0的点的集合一定可以到达所有点。且易知入度为0的点必然要包含在结果点集中, 因为除了其本身,没有任何一个点可以到达该点。因此只要统计所有入度为0的点即可。
算法的复杂度:
算法的时间复杂度为O(m + n)。因为额外产生一个to的set,所以算法的空间复杂度为O(n)。
代码:
class Solution {
public:
vector<int> findSmallestSetOfVertices(int n, vector<vector<int>>& edges) {
set<int> to;
vector<int> res;
for(int i = 0; i < edges.size(); ++i)
to.insert(edges[i][1]);
for(int i = 0; i < n; ++i)
{
if(to.count(i) == 0)
res.push_back(i);
}
return res;
}
};
5481. 得到目标数组的最少函数调用次数(第33场双周赛issue 3)
思路:
从二进制的角度考虑,加法为将末尾数置为1,乘法是将数组中所有的数字左移一位。因此我们只要考虑最大的数左移的次数就是所有数字的左移次数也即乘法次数,最后再统计一下所有数的二进制表示中1的个数即为加法次数。
算法的复杂度:
算法的时间复杂度为O(n)。因为没有产生额外空间,所以算法的空间复杂度为O(1)。
代码:
class Solution {
public:
int minOperations(vector<int>& nums) {
int MaxNum = 0;
int res = 0;
for(int i = 0; i < nums.size(); ++i)
{
if(nums[i] > MaxNum)
MaxNum = nums[i];
while(nums[i] != 0)
{
res += (nums[i] % 2);
nums[i] /= 2;
}
}
while(MaxNum != 0)
{
++res;
MaxNum /= 2;
}
--res;
return res;
}
};