• 数组中出现次数超过一半的数字、替换空格、重建二叉树


    1、数组中出现次数超过一半的数字

    本题考点: 数组使用,简单算法的设计 牛客链接

    题目描述:
    给一个长度为 n 的数组,数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
    例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。

    数据范围:50000n≤50000,数组中元素的值 0≤val≤10000
    要求:空间复杂度:O(1),时间复杂度 O(n)
    输入描述:
    保证数组输入非空,且保证有解

    解题思路:
    思路一:定义map,使用<数字,次数>的映射关系,最后统计每个字符出现的次数
    思路二:排序,出现次数最多的数字,一定在中间位置。然后检测中间出现的数字出现的次数是否符合要求
    思路三:目标条件:目标数据超过数组长度的一半,那么对数组,我们同时去掉两个不同的数字,到最后剩下的数就是该数字。将数组遍历一遍统计一下数字出现次数进行最终判断。
    代码

    class Solution {
    public:
        int MoreThanHalfNum_Solution(vector<int> numbers) {
            //方法一:哈希法
            // unordered_map ump;
            // for(auto& num : numbers)
            // {
            //     ump[num]++;
            // }
            // int ret = 0;
            // for(auto& up : ump)
            // {
            //     if(up.second > (numbers.size() / 2))
            //         ret = up.first;
            // }
            // return ret;
            
            //方法二:排序法
            //先排序找到中间值,在统计中间值的次数
            // sort(numbers.begin(), numbers.end());
            // int mid = numbers[numbers.size() / 2];
            // int count = 0;
            // for(int num : numbers)
            // {
            //     if(num == mid)
            //         ++count;
            // }
            // if(count > (numbers.size() / 2))
            //     return mid;
            // return 0;
    
            //方法三: 若是有超过一半的数字,那么遍历一遍一次去掉两个不相同的数字,
            //剩下的数字则可能是要找的数字,通过遍历统计次数来判别
            
            int number = numbers[0]; //可以采取不同的数量进行抵消的思路
            int count = 1;
            for(int i = 1; i < numbers.size(); i++)
            {
                if(count == 0) //如果当前times是0,说明之前的不同抵消完了
                {
                	number = numbers[i];
                	count = 1;
    			}
                else if(number == numbers[i])
                {
                     count++;
                }
                else
                {
    				count--;
    			}      
            }
         
            count = 0;
            for(int num : numbers)
            {
                if(num == number)
                    ++count;
            }
            
            return count > numbers.size() / 2 ? number : 0;
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64

    2、替换空格

    本题考点: 字符串相关,特性观察,临界条件处理 牛客链接

    题目描述:
    请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

    解题思路:
    这题比较简单,题中是一个空格替换成三个字符,所以替换完成后字符串一定会变成,题中给我们传过来的是一个指针,所以不用担心扩容的问题。故我们可以先统计出空格的个数算出最后位置的下标,从后向前一个个挪动就可以了。

    代码:

    class Solution {
    public:
    	void replaceSpace(char *str,int length) {
    		if(nullptr == str || length == 0)
    			return;
    
    		int count = 0;
    		for(int i = 0; str[i] != '\0'; i++)
    		{
    			if(str[i] == ' ')
    				count++;
    		}
    		cout << count << endl;
    		int old_index = length - 1;
    		int new_index = length + 2 * count - 1;
    		while(old_index >= 0 || new_index >= 0)
    		{
    			if(str[old_index] == ' ')
    			{
    				str[new_index--] = '0';
    				str[new_index--] = '2';
    				str[new_index--] = '%';
    				old_index--;
    			}
    			else
    			{
    				str[new_index] = str[old_index];
    				old_index--;
    				new_index--;
    			}		
    		}
    	}
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    3、从尾到头打印链表

    本题考点: 链表相关,多结构混合使用,递归。牛客链接

    题目描述:

    输入一个链表的头节点,按链表从尾到头的顺序返回每个节点的值(用数组返回)。

    如输入{1,2,3}的链表如图: 在这里插入图片描述

    返回一个数组为[3,2,1]

    0 <= 链表长度 <= 10000
    示例1
    输入: {1,2,3}
    返回值: [3,2,1]

    解题思路:
    这道题整体解决思路很多,可以使用stack,可以将数据保存数组后逆序数组,也可以递归,前两种比较简单,我们使用递归来写一下:

    代码:

    class Solution {
    public:
        void _printListFromTailToHead(ListNode* head, vector<int>& v)
        {
            if(head == nullptr)
                return;
            _printListFromTailToHead(head->next, v);
            v.push_back(head->val);
        }
        vector<int> printListFromTailToHead(ListNode* head) {
            vector<int> v;
            _printListFromTailToHead(head, v);
            return v;
        }
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4、重建二叉树

    本题考点: 遍历理解,递归 牛客链接

    题目描述:
    在这里插入图片描述
    解题思路:

    在这里插入图片描述

    代码:

    class Solution {
    public:
        TreeNode* _reConstructBinaryTree(vector<int> pre,vector<int> vin, int& index, int left, int right)
        { 
             //返回条件
            if(left > right)
                return nullptr;
            
            TreeNode* root = new TreeNode(pre[index]); //构建根
           
            int rooti = left;
            while(rooti <= right)
            {
                if(pre[index] == vin[rooti])
                    break;
                else
                    ++rooti;
            }
    
            index++;
            root->left = _reConstructBinaryTree(pre, vin, index, left, rooti - 1);
            root->right = _reConstructBinaryTree(pre, vin, index, rooti + 1, right);
    
            return root;
        }
        TreeNode* reConstructBinaryTree(vector<int> pre,vector<int> vin) {
            if(pre.empty() || vin.empty())
                return nullptr;
    
            int index = 0;
            return _reConstructBinaryTree(pre, vin, index, 0, pre.size() - 1);
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
  • 相关阅读:
    javaDoc文档注释,在线文档生成,基础详解,idea加载生成doc文档
    jvm打破砂锅问到底- 为什么要标记或记录跨代引用
    HashMap底层原理put()与resize()扩容
    【前端】psd到html切图,包含ps切图
    深度学习模型理解-CNN-手写数据字代码
    2023物联网新动向:WEB组态除了用于数据展示,也支持搭建业务逻辑,提供与蓝图连线和NodeRed规则链类似的可视化编程能力
    css 10-13
    无碳越障S型小车总体设计(lunwen+工序卡+过程卡+cad图纸+proe三维图纸+运动仿真视频)
    6.19-MyBatis源码—体系介绍和配置文件解析源码剖析
    Nginx 代理WebSocket
  • 原文地址:https://blog.csdn.net/C_Trip/article/details/127999025