先判断当前反转后的数是否超过范围,若在范围内则逐位反转
int reverse(int x) {
int rev = 0;
while (x != 0) {
if (rev < INT_MIN / 10 || rev > INT_MAX / 10)
return 0;
int digit = x % 10;
x /= 10;
rev = rev * 10 + digit;
}
return rev;
}
1、先进行边界判断,为0或者末位为0则返回
2、只反转一半即可,防止全部反转超过上限
3、直接判断反转后的数是否相等,不用按位判断
bool isPalindrome(int x) {
// 特殊情况:
// 如上所述,当 x < 0 时,x 不是回文数。
// 同样地,如果数字的最后一位是 0,为了使该数字为回文,
// 则其第一位数字也应该是 0
// 只有 0 满足这一属性
if (x < 0 || (x % 10 == 0 && x != 0))
return false;
int revertedNumber = 0;
while (x > revertedNumber) {
revertedNumber = revertedNumber * 10 + x % 10;
x /= 10;
}
// 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
// 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
// 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
return x == revertedNumber || x == revertedNumber / 10;
}
};
直接求n次方复杂度太高,可以使用平方减小复杂度,每次n为奇数时先多乘一个x再平方,这就是快速幂的方法
double myPow(double x, int n) {
if(n == 0) return 1;
double ans = 1;
//必须用num,n是32位有符号整数,int存不下
long num = n;
if(n < 0) {
//必须将n存为整数,不然无法移位
num = -num;
x = 1/x;
}
while(num){
if(num%2==1) ans *= x;
x *= x;
num=num/2;
}
return ans;
}
从后往前遍历数组,依次加1,到不进位为止返回,如果遍历到开始时,用vector的insert方法插入一个1
vector<int> plusOne(vector<int>& digits) {
for(int i=digits.size()-1; i>=0; i--) {
digits[i]++;
if(digits[i] == 10) digits[i] = 0;
else return digits;
}
digits.insert(digits.begin(), 1);
return digits;
}
一个数和自己异或运算等于0,和0异或运算等于自己,并且异或运算满足交换律,所以对所有数字从头到尾异或运算一遍,出现两次的数都会变为0,最后只剩下只出现一次的数字,这个解法相比于哈希表没有额外的空间复杂度
class Solution {
public:
int singleNumber(vector<int>& nums) {
int ret = 0;
for (auto e: nums) ret ^= e;
return ret;
}
};
1、本题与上一题的区别是,多了一个只出现一次的数字,直接异或不行,需要采用分组异或
2、首先过一遍异或,得到结果中找到第一个为1的数字,这个数字表示两个数结果肯定不一样
3、根据这一位数字与所有数进行且运算,将数组分为两组,再分别进行异或,得到两个答案
class Solution {
public:
vector<int> singleNumbers(vector<int>& nums) {
int x = 0, y = 0, n = 0, m = 1;
for(int num : nums) // 1. 遍历异或
n ^= num;
while((n & m) == 0) // 2. 循环左移,计算 m
m <<= 1;
for(int num : nums) {
// 3. 遍历 nums 分组
if(num & m) x ^= num; // 4. 当 num & m != 0
else y ^= num; // 4. 当 num & m == 0
}
return vector<int> {
x, y}; // 5. 返回出现一次的数字
}
};
1-4没有0,5-9有1个0,10-14有2个0,每隔5个数增加一个0,计算有多少个5即可
int trailingZeroes(int n) {
int ans=0;
while(n>0){
ans+=n/5;
n/=5;
}
return ans;
}
1、移位运算符<<代表:需要移位的数字 << 移位的次数
2、通过1不停的移位,和原数字进行与操作,判断二进制下1的个数
class Solution {
public:
int hammingWeight(uint32_t n) {
//位运算,移位运算符<<
int num=0;
for(int i=0;i<32;i++)
if(n&(1<<i))
num++;
return num;
}
};
洗牌算法,从后往前遍历,每个位置和前面的随机交换即可
class Solution {
private:
vector<int> original;
public:
Solution(vector<int>& nums) {
original = nums;
}
vector<int> reset() {
return original;
}
vector<int> shuffle() {
vector<int> nums(original); //用原数组来初始化新数组
for (int i = nums.size() - 1; ~i; i -- ) //从后往前遍历
swap(nums[i], nums[rand() % (i + 1)]); //rand()能随机生成0到最大随机数的任意整数
return nums; //rand() % (i + 1)能随机生成0到i中的任意整数
}
};
class Solution {
public:
string validIPAddress(string IP) {
regex ipv4("(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])");
regex ipv6("([0-9a-fA-F]{1,4}\\:){7}[0-9a-fA-F]{1,4}");
if (regex_match(IP, ipv4)) return "IPv4";
else if (regex_match(IP, ipv6)) return "IPv6";
else return "Neither";
}
};
class Solution {
public:
bool validIPv4(string IP) {
if (IP.empty() || IP.back() == '.' || IP.front() == '.')
return false;
int digit = 0,dot_ind = -1,dot_num = 0;
for (int i = 0; i < IP.size(); ++i) {
if (IP[i] == '.') {
if (i - dot_ind == 1)
return false;
digit = 0;
dot_ind = i;
++dot_num;
} else if (IP[i] >= '0' && IP[i] <= '9') {
if (i - dot_ind > 1 && digit == 0)
return false;
digit = 10 * digit + IP[i] - '0';
if (digit > 255)
return false;
} else {
return false;
}
}
return dot_num == 3;
}
bool validHex(char c) {
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
bool validIPv6(string IP) {
if (IP.empty() || IP.back() == ':' || IP.front() == ':')
return false;
string elem;
int colon_ind = -1;
int colon_num = 0;
for (int i = 0; i < IP.size(); ++i) {
if (IP[i] == ':') {
if (elem.empty())
return false;
elem.clear();
colon_ind = i;
++colon_num;
} else if (validHex(IP[i])) {
elem += IP[i];
if (elem.size() > 4)
return false;
} else {
return false;
}
}
return colon_num == 7;
}
string validIPAddress(string IP) {
if (validIPv4(IP))
return "IPv4";
if (validIPv6(IP))
return "IPv6";
return "Neither";
}
};
用拒绝采样法,两个rand7不能直接相乘,会导致生成的数概率不相等
用rand7算出1-49,拒绝41-49,保留1-40算出rand10
int rand10() {
int add;
do{
int row=rand7();
int col=rand7();
//两个rand7不能直接相乘,会导致数概率不相等
add=(row-1)*7+col;
}while(add>40) ;
return 1+(add-1)%10;
}