剑指offer读书笔记:第六章,面试中的各项个能力01

这里写图片描述

问题01 数字在排序数字中的数量

这里写图片描述

最笨的方法使用Map统计遍历,但是题目是有序数组,所以必然是二分查找,可以去寻找key的上一个元素和下一个元素,时间都是O(lon(n)),然后计算范围即可。

问题02 二叉树的深度

这里写图片描述

这个实在是太简单了,直接DFS深度优先遍历即可

问题03 数组中只出现一次的数字

这里写图片描述

  • 先考虑一个数组里只有一个数出现一次,其他两个数都出现两次的情况:一个数跟自己异或后为0,一个数组里只有一个数出现一次其他两次,挨个异或后最后得到的结果就是只出现一次的那个数。
//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        if (array == null || array.length == 0) {
            return;
        }
        if (array.length < 2) {
            num1[0] = 0;
            num2[0] = 0;
            return;
        }
        int temp1 = array[0];
        for (int i = 1; i < array.length; i++) {
            temp1 = temp1 ^ array[i];
        }
        int firstBit = 0;
        while (((temp1 & 1) == 0) && (firstBit < 32)) {
            firstBit++;
            temp1 = temp1 >> 1;
        }
        num1[0] = 0;
        num2[0] = 0;
        for (int i = 0; i < array.length; i++) {
            if (isBit(array[i], firstBit)) {
                num1[0] = num1[0] ^ array[i];
            } else {
                num2[0] = num2[0] ^ array[i];
            }
        }
        return;
    }
    public boolean isBit(int num, int indexBit) {
        num = num >> indexBit;
        return (num & 1) == 1;
    }
}

问题04 和为s的两个数字VS和为s的连续整数序列

这里写图片描述

对于上题,是指left和right指针,双指针遍历判断即可,千万不要暴力求解。

这里写图片描述

分析如下:
这里写图片描述

代码如下:

#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>
#include <stack>
#include <string>
#include <climits>
#include <algorithm>
#include <sstream>
#include <functional>
#include <bitset>
#include <numeric>
#include <cmath>
#include <regex>
#include <iomanip>
#include <cstdlib>
#include <ctime>

using namespace std;

class Solution
{
public:
    vector<int> getOne(int begin, int end)
    {
        vector<int> one;
        for (int i = begin; i <= end; i++)
            one.push_back(i);
        return one;
    }
    vector<vector<int> > FindContinuousSequence(int sum)
    {
        vector<vector<int> > res;
        if (sum < 1 + 2)
            return res;
        int left = 1, right = 2, mid = (1 + sum) / 2;
        int curSum = left + right;
        while (left < mid)
        {
            if (curSum == sum)
                res.push_back(getOne(left, right));
            else if (curSum > sum)
            {
                while (curSum > sum && left < mid)
                {
                    curSum -= left;
                    left++;
                }
                if (curSum == sum)
                    res.push_back(getOne(left, right));
            }
            right++;
            curSum += right;
        }
        return res;
    }
};

问题05 翻转单词顺序 VS 左旋转字符串

这里写图片描述

直接使用C++的stringstream来做,很方便,或者遍历空格来翻转

这里写图片描述

直接旋转吧,

其实字符串处理对于C++和Java来说还是很容易去做的,注意考虑各种极端情况即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值