1.给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
解:通过采用两两异或,可以把相同的数字变为0,留下单独存在的那个数字
代码:
class Solution {
public:
int singleNumber(vector<int>& nums) {
int result = 0;
for (int i = 0; i < nums.size(); i++)
result ^= nums[i];
return result;
}
};
int main()
{
Solution s1;
vector < int> ss = { 4,1,2,1,2 };
vector<int> s;
cout<<s1.singleNumber(ss);
return 0;
}
2.给定一个二维平面,平面上有 n 个点,求最多有多少个点在同一条直线上。
示例 1:
输入: [[1,1],[2,2],[3,3]]
输出: 3
解释:
^
|
| o
| o
| o
+------------->
0 1 2 3 4
代码:
class Solution {
public:
int maxPoints(vector<vector<int>>& points) {
int res = 0;
for (int i = 0; i < points.size(); ++i) {
map<pair<int, int>, int> m;
int duplicate = 1;
for (int j = i + 1; j < points.size(); ++j) {
if (points[i][0] == points[j][0] && points[i][1] == points[j][1]) {
++duplicate; continue;
}
int dx = points[j][0] - points[i][0];
int dy = points[j][1] - points[i][1];
int d = gcd(dx, dy);
++m[{dx / d, dy / d}];
}
res = max(res, duplicate);
for (auto it = m.begin(); it != m.end(); ++it) {
res = max(res, it->second + duplicate);
}
}
return res;
}
int gcd(int a, int b) {
return (b == 0) ? a : gcd(b, a % b);
}
};
int main()
{
Solution s1;
vector < vector<int>> ss = { {1,1},{2,2},{3,3} };
vector<int> s;
cout<<s1.maxPoints(ss);
return 0;
}
3.给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数。
如果小数部分为循环小数,则将循环的部分括在括号内。
示例 1:
输入: numerator = 1, denominator = 2
输出: "0.5"
示例 2:
输入: numerator = 2, denominator = 3
输出: "0.(6)"
解:先确定整数部分,并确定除下来后的正负号,若取模为0则表示刚好整除,否则包含小数部分,进一步确定小数,循环小数的特征是取模后的值始终相等,因此可以使用map来确定前后两次是否相等。
代码:
class Solution {
public:
string fractionToDecimal(int numerator, int denominator) {
int s1 = numerator >= 0 ? 1 : -1; //分子
int s2 = denominator >= 0 ? 1 : -1;//分母
long long num = abs((long long)numerator);
long long den = abs((long long)denominator);
long long out = num / den;
long long rem = num % den;
unordered_map<long long, int> m;
string res = to_string(out);//整数部分转为字符串
//算符号
if (s1*s2 == -1 && (out > 0 || rem > 0))
res = "-" + res;//判断正负
if (rem == 0)
return res;//刚好为整数
res += ".";
string s = "";
int pos = 0;
while (rem != 0)//含有小数部分
{
if (m.find(rem) != m.end())
{
s.insert(m[rem], "(");
s += ")";
return res + s;
}
m[rem] = pos;
s += to_string((rem * 10) / den);
rem = (rem * 10) % den;//进一步确定小数位
++pos;
}
return res + s;
}
};
int main()
{
Solution s1;
vector < vector<int>> ss = { {1,1},{2,2},{3,3} };
vector<int> s;
cout<<s1.fractionToDecimal(33,100);
return 0;
}
4.给定一个整数 n,返回 n! 结果尾数中零的数量。
输入: 5
输出: 1
解释: 5! = 120, 尾数中有 1 个零.
解:对于阶乘,确定0的个数即计算n中包含多少个5.
代码:
class Solution {
public:
int trailingZeroes(int n) {
int res = 0;
for (int i = 1;; i++) {
int number = n / pow(5, i);//确定有多少个能被5的幂次方整除,计算n中有多少个5
if (number == 0)
break;
res += number;
}
return res;
}
};
int main()
{
Solution s1;
cout<<s1.trailingZeroes(5);
return 0;
}
5.颠倒给定的 32 位无符号整数的二进制位。
示例 1:
输入: 00000010100101000001111010011100
输出: 00111001011110000010100101000000
解释: 输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596, 因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。
示例 2:
输入:11111111111111111111111111111101
输出:10111111111111111111111111111111
解释:输入的二进制串 11111111111111111111111111111101 表示无符号整数 4294967293, 因此返回 3221225471 其二进制表示形式为 10101111110010110010011101101001。
代码:
class Solution {
public:
uint32_t reverseBits(uint32_t n) {
uint32_t res = 0;
for (int i = 0; i < 32; i++)
{
res = res << 1;
res = res + (n & 1);
n = n >> 1;
}
return res;
}
};
int main()
{
Solution s1;
cout<<s1.reverseBits(43261596);
return 0;
}
6.编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。
解:要求二进制中1的个数,则应该从最后一位依次向左判断有多少个1,即每判断完一位,则应该减去1,判断前面的位数1,判断过的位应该全部为0.
代码:
class Solution {
public:
int hammingWeight(uint32_t n) {
int count=0;
while(n)
{
++count;
n=n&(n-1);
}
return count;
}
};
int main()
{
Solution s1;
cout<<s1.hammingWeight(21);
return 0;
}
7.统计所有小于非负整数 n 的质数的数量。
示例:
输入: 10
输出: 4
解释: 小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。
代码:
class Solution {
public:
int countPrimes(int n) {
vector<int> p(n + 1, 1);
int res = 0;
if (n < 2) return 0;
for (int i = 2; i < n; i++)
{
if (p[i] == 1) {
res += 1;
int j = i + i;
while (j < n) {
p[j] = 0;
j += i;
}
}
}
return res;
}
};
int main()
{
Solution s1;
cout<<s1.countPrimes(45);
return 0;
}
8.给定一个包含 0, 1, 2, ..., n
中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。
示例 1:
输入: [3,0,1]
输出: 2
解:运用位运算来完成,思路为temp ^ nums[ i ] ^ (i + 1),这里的temp值从0开始,因为nums 的值是从0开始,而(i + 1)则是为了取到自然数1,2,3,4,5...等。
运算规则如下:
假如目标数组nums 值 为 0,1,2,4
自然数对应为1, 2,3,4
0 ^ 1 ^ 0 = 1
1 ^ 2 ^ 1 = 2
2 ^ 3 ^ 2 = 3
3 ^ 4 ^ 4 = 3
代码:
class Solution {
public:
int missingNumber(vector<int>& nums) {
int temp = 0;
for (int i = 0; i < nums.size(); i++)
{
temp = temp ^ (i + 1) ^ nums[i];
}
return temp;
}
};
int main()
{
Solution s1;
vector<int> ss = { 2,4,0,1 };
cout<<s1.missingNumber(ss);
return 0;
}
9.给定一个整数,写一个函数来判断它是否是 3 的幂次方。
示例 1:
输入: 27
输出: true
解:判断是否为3的幂次方,可以通过while循环不断整除,若余数为1则代表是幂次方。
代码:
class Solution {
public:
bool isPowerOfThree(int n) {
if (n == 0) return false;
while (n % 3 == 0) n /= 3;
if (n == 1) return true;
return false;
}
};
int main()
{
Solution s1;
cout<<s1.isPowerOfThree(99);
return 0;
}