《剑指 Offer II》—整数02

学习计划链接

剑指offer——学习计划

题目解析

1. 剑指 Offer II 004. 只出现一次的数字

1) 问题描述

在这里插入图片描述

2) 思路分析

法1:排序+遍历

  1. 排序
  2. 判断相邻的两个数是否相等,若相等,则直接跳到第四个数,若不等,则说明该数是要找的单数

法2:哈希表统计次数+遍历

  1. 使用stl的unordered_map容器(哈希表)统计次数;
  2. 遍历哈希表查找次数为1的数。

法3:位运算
(原理:按位将每一位相加,并进行%3操作,所得结果即为单一的数在某位的值)

  1. 自高位向低位取每一位,求和;
  2. 针对每一位进行%3操作,得单一数字在该位的值。
  3. 计算该数。

3) leetcode链接

剑指 Offer II 004. 只出现一次的数字

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存储+位操作:

  1. 定义一个容量为words数组大小的vector 类型变量,其每一个元素用来存储每一个字符串中包含的字母所占位(将某字母所在位置置为1——对应表示某字符串所含的字母)。
  2. 遍历words数组,记录数组中每个元素所包含的字母信息;
  3. 遍历找出不包含相同字符的两个字符串(按位&操作,若两个字符串相与为0,则说明其不存在相同字符),并计算其长度的乘积并与最大乘积max进行比较,若其大于max,则更新max值。直到结束。

3) leetcode链接

剑指 Offer II 005. 单词长度的最大乘积

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) 思路分析

双指针法:

  1. 两个指针分别指向numbers头和尾。
  2. 将指针指向的元素相加。
  3. 判断相加的结果。
    若所得值==target,则,将两个指针插入返回数组中并进行返回;
    若所得值>target,则尾指针进行–操作;
    若所得值<target,则头指针++。

3) leetcode链接

剑指 Offer II 006. 排序数组中两个数字之和

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>();

    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值