目录
学习计划链接
题目解析
1. 剑指 Offer II 004. 只出现一次的数字
1) 问题描述
2) 思路分析
法1:排序+遍历
- 排序
- 判断相邻的两个数是否相等,若相等,则直接跳到第四个数,若不等,则说明该数是要找的单数
法2:哈希表统计次数+遍历
- 使用stl的unordered_map容器(哈希表)统计次数;
- 遍历哈希表查找次数为1的数。
法3:位运算
(原理:按位将每一位相加,并进行%3操作,所得结果即为单一的数在某位的值)
- 自高位向低位取每一位,求和;
- 针对每一位进行%3操作,得单一数字在该位的值。
- 计算该数。
3) leetcode链接
4) 代码实现
class Solution {
public:
//3.位运算(按位将每一位相加,并进行%3操作,所得结果即为单一的数在某位的值)
int singleNumber(vector<int>& nums) {
long long ret=0;
//1.自高位向低位取每一位,求和。
for(int i=31;i>=0;i--)
{
int bitSum=0;
for(auto & n:nums)
{
if(n&(1<<i))
bitSum++;
}
//2.针对每一位进行%3操作,得单一数字在该位的值
bitSum%=3;
//3.计算要查找的数的值
ret=ret*2+bitSum;
}
return ret;
}
//2. hash统计次数+遍历(判断次数)
int singleNumber2(vector<int>& nums) {
//1.unordered_map统计次数
unordered_map<int,int> hash;
for(auto &n:nums)
{
// if(hash.find(n)==hash.end() )
// hash[n]=1;
// else
// hash[n]+=1;
hash[n]++;
}
//2.遍历判断
for(auto &h:hash)
{
if(h.second==1)
return h.first;
}
return -1;
}
//1. 排序+遍历(相邻比较)
int singleNumber1(vector<int>& nums) {
//1.排序
sort(nums.begin(),nums.end());
//2.判断相邻的两个数是否相等,若相等,则直接跳到第四个数,若不等,则说明该数是要找的单数
for(int i=0;i<nums.size()-1;++i)
{
if(nums[i]==nums[i+1])
{
i+=2;
}
else
{
return nums[i];
}
}
return nums[nums.size()-1];
}
};
2. 剑指 Offer II 005. 单词长度的最大乘积
1) 问题描述
2) 思路分析
hash存储+位操作:
- 定义一个容量为words数组大小的vector 类型变量,其每一个元素用来存储每一个字符串中包含的字母所占位(将某字母所在位置置为1——对应表示某字符串所含的字母)。
- 遍历words数组,记录数组中每个元素所包含的字母信息;
- 遍历找出不包含相同字符的两个字符串(按位&操作,若两个字符串相与为0,则说明其不存在相同字符),并计算其长度的乘积并与最大乘积max进行比较,若其大于max,则更新max值。直到结束。
3) leetcode链接
4) 代码实现
class Solution {
public:
int maxProduct(vector<string>& words) {
//1. 定义一个容量为words数组大小的vector<int> 类型变量,其每一个元素用来存储每一个字符串中包含的字母所占位(将某字母所在位置置为1——对应表示某字符串所含的字母)。
//2. 遍历words数组,记录数组中每个元素所包含的字母信息;
//3. 找出不包含相同字符的两个字符串(按位&操作,若两个字符串相与为0,则说明其不存在相同字符),计算其长度的乘积并与最大乘积max进行比较,若其大于max,则更新max值。直到结束。
int ret=0;
vector<int> CharBit(words.size(),0);
for(int i=0;i<words.size();++i)
{
for(auto &ch:words[i])
{
CharBit[i] |= (1<< (ch-'a'));
}
}
for(int i=0;i<words.size()-1;i++)
{
for(int j=i+1;j<words.size();j++)
{
if((CharBit[i]&CharBit[j])==0)
{
int mul=words[i].size() * words[j].size();
ret=max(mul,ret);
}
}
}
return ret;
}
};
3. 剑指 Offer II 006. 排序数组中两个数字之和
1) 问题描述
2) 思路分析
双指针法:
- 两个指针分别指向numbers头和尾。
- 将指针指向的元素相加。
- 判断相加的结果。
若所得值==target,则,将两个指针插入返回数组中并进行返回;
若所得值>target,则尾指针进行–操作;
若所得值<target,则头指针++。
3) leetcode链接
4) 代码实现
class Solution {
public:
vector<int> twoSum(vector<int>& numbers, int target) {
//1.两个指针分别指向numbers头和尾。
//2.将指针指向的元素相加。
//3.判断相加的结果。若所得值==target,则,返回将两个指针插入返回数组中并进行返回;若所得值>target,则尾指针进行--操作;若所得值<target,则头指针++。
int head=0,tail=numbers.size()-1;
vector<int> ret;
while(head<tail)
{
int sum=numbers[head]+numbers[tail];
if(sum==target)
{
ret.push_back(head);
ret.push_back(tail);
return ret;
}
else if(sum>target)
{
tail--;
}
else
{
head++;
}
}
return vector<int>();
}
};