wy的leetcode刷题记录_Day5
788.旋转数字
今天的每日一题是:788. 旋转数字
题目介绍
我们称一个数 X 为好数, 如果它的每位数字逐个地被旋转 180 度后,我们仍可以得到一个有效的,且和 X 不同的数。要求每位数字都要被旋转。
如果一个数的每位数字被旋转以后仍然还是一个数字, 则这个数是有效的。0, 1, 和 8 被旋转后仍然是它们自己;2 和 5 可以互相旋转成对方(在这种情况下,它们以不同的方向旋转,换句话说,2 和 5 互为镜像);6 和 9 同理,除了这些以外其他的数字旋转以后都不再是有效的数字。
现在我们有一个正整数 N, 计算从 1 到 N 中有多少个数 X 是好数?
示例:
输入: 10
输出: 4
解释: 在[1, 10]中有四个好数: 2, 5, 6, 9。
注意 1 和 10 不是好数,因为他们在旋转之后不变。
思路
分析题目得知,对于数字3,4,7,他们进行旋转后不是数字,也就是出现其中数字之一就无法称之为好数;同时好数的另一个条件就是与原来的数值不相同,这就说明好数不能全是由0,1,8组成的,此时我们设立一个计数器来表示出现该三个数字的次数,如果次数正好等于数字的位数则也不能称之为好数。遍历从1-n,对于每一个元素我们使用to_string函数来将一个int型的数字转换成string类型,然后遍历该string,设立string_n来表示长度也就是数字的位数,然后再根据一开始分析的情况来判断是否为好数。
代码
class Solution {
public:
int rotatedDigits(int n) {
//0 1 2 5 6 8 9是ok的 也就是3 4 7 不ok
int ans=n;
for(int i=1;i<=n;i++)
{
string temp=to_string(i);
int temp_n=temp.size();
int flag=0;
for(int j=0;j<temp_n;j++)
{
//flag=0;
if(temp[j]=='3'||temp[j]=='4'||temp[j]=='7')
{
ans--;
break;
}
if(temp[j]=='0'||temp[j]=='1'||temp[j]=='8')
flag++;
}
if(flag==temp_n)
ans--;
}
return ans;
}
};
收获
1.学习了to_string的用法
2.巩固了编程水平
416. 分割等和子集
题目介绍
给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
思路
1.确定dp数组含义:dp[i]表示背包总容量是i,最⼤可以凑成i的⼦集总和为dp[i]
2.确定dp数组递推公式:dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])
3.初始化:
// 题⽬中说:每个数组中的元素不会超过 100,数组的⼤⼩不会超过 200
// 总和不会⼤于20000,背包最⼤只需要其中⼀半,所以10001⼤⼩就可以了
vector<int> dp(10001, 0);
代码
class Solution {
public:
bool canPartition(vector<int>& nums) {
int n=nums.size();
int sum=0;
for(int i=0;i<n;i++)
{
sum+=nums[i];
}
vector<int> dp(10001, 0);
if(sum%2!=0)
{
return false;
}
int target=sum/2;
for(int i = 0; i < nums.size(); i++) {
for(int j = target; j >= nums[i]; j--) { // 每⼀个元素⼀定是不可重复放⼊,所以从⼤到⼩遍历
dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);
}
}
// 集合中的元素正好可以凑成总和target
if (dp[target] == target)
return true;
return false;
}
};
收获
熟悉背包问题