函数传参问题,桶排序去重,分治递归,摩尔投票求数组众数,数组中心下标求法

news2024/11/15 19:34:32

TIPS

1. 我们都知道,地址,指针这两者是完全等价的概念,但是有微小的差别。地址的话是不能够修改的(比如说数组名++就是违法的),而指针的话可以++与--。

2. 以后一旦在代码里面看到字符char类型的,眼睛里面默认就要把它想象成ASCII码,比如定义

int arr['10']是完全正确的,那个字符10说白了,在计算机里面就是一个数字罢了。

3. 

4.  

题目1 (有关于函数调用,递归与参数问题)

答案:“suieue”

经验总结:

1. 函数调用传递参数的时候,一定一定要注意是传值调用还是传址调用。一定一定要特别明确:如果是传值调用,那么形参就是实参的一份临时拷贝(它们名字可能一模一样极具迷惑性,但是无论如何也掩盖不了临时拷贝的事实),也正是因为当传值调用时形参与实参的关系是临时拷贝,所以现在假设我有一个函数,一旦进入到其调用函数的内部,里面各种五花八门的变换对于我本函数接下来代码语句的数据等将不会有任何影响。

2. 那么接下来回到这道题目,有人可能就要问,这不是传址调用吗?没错,确实是传址调用。那是你要知道的是:传址调用确实是在函数的内部与外部建立了联系,但不要偷换概念,那个的意思在于可以通过指针解引用然后进行修改啊运算啊等等然后等到调用函数跳出来后,之前那些"修改痕迹"还是被保留下来,"持续发挥着影响"。但是,当传址调用时,我在调用函数里面的参数指针也是新的指针(虽然名字可能与原来指针相同,但两者是完全不搭嘎的东西,只不过一开始都指向同一空间而已),里面新指针的变化,对于本函数来说没有任何影响
3. ++与--都是有副作用的。
4. 字符char的话,其实我们也都知道,它在计算机里面也属于整型,因为它本质上就是ACSII码而已。虽然看起来花里胡哨的。 

寻找数组的中心下标

题目链接:https://leetcode.cn/problems/find-pivot-index/ 

题目:

代码1:

//弱智暴力解法
int pivotIndex(int* nums, int numsSize)
{
    int i = 0;
    int j1 = 0;
    int j2 = 0;
    for (i = 0; i < numsSize; i++)
    {
        int sum_left = 0;
        int sum_right = 0;
        for (j1 = 0; j1 <= (i - 1); j1++)
        {
            sum_left += *(nums + j1);
        }
        for (j2 = (i + 1); j2 < numsSize; j2++)
        {
            sum_right += *(nums + j2);
        }
        if (sum_left == sum_right)
        {
            return i;
        }
    }
    return -1;
}

代码2:

//稍微动点脑子的做法
int pivotIndex(int* nums, int numsSize)
{
    int i = 0;
    int j = 0;
    int sum_right = 0;
    for (j = 1; j < numsSize; j++)
    {
        sum_right += *(nums + j);
    }
    int sum_left = 0;
    for (i = 0; i < numsSize; i++)
    {
        if (i > 0)
        {
            sum_left += *(nums + i - 1);
            sum_right -= *(nums + i);
        }
        if (sum_left == sum_right)
        {
            return i;
        }
    }
    return -1;
}

代码3:

int pivotIndex(int* nums, int numsSize)
{
    int i=0;
    int total=0;
    for (i=0;i<numsSize;i++)
    {
        total+=*(nums+i);
    }
    //
    int sum_left=0;
    for (i=0;i<numsSize;i++)
    {
        if (2*sum_left==total-*(nums+i))
        {
            return i;
        }
        sum_left+=*(nums+i);
    }
    return -1;
}

经验总结:

1. 这个才是真正经过推敲过的代码。运行的效率会高很多。我们需要慢慢改正优化,把痤的代码完善起来。
2. 也就是说,如果有时候能通过数学推演得出一个表达式那就最好不过了,像这道题:sum_right=total-nums[ i ]-sum_left这个表达式如果脑海中知晓的话,在等于sum_left,就可以省事很多.

字符串不同字符个数统计(桶排序思想)

题目链接:https://www.nowcoder.com/practice/eb94f6a5b2ba49c6ac72d40b5ce95f50?tpId=37&&tqId=21233&rp=1&ru=/ta/huawei&qru=/ta/huawei/question-ranking

题目:

代码:

#include <stdio.h>
#include <string.h>
int main()
{
    int i=0;
    int arr1[128]={0};
    int count=0;
    //
    char arr[500]={0};
    scanf("%s",arr);
    int sz=strlen(arr);
    //
    for (i=0;i<sz;i++)
    {
        int num=arr[i];
        arr1[num]=1;
    }
    //
    for (i=0;i<=127;i++)
    {
        if (arr1[i]==1)
        {
            count++;
        }
    }
    printf("%d\n",count);
    return 0;
}

经验总结:

1. 桶排序的精髓在于:
  1. 把待排序的数字与新数组(全为0)的下标联系起来。
  2. 联系起来之后在对应下标的数组元素里面放入1作为标记。

  3. 打印的时候打印的是数组的下标。

2. 桶排序就相当于把一堆数字放进一个新桶(就是元素全为0的数组)里面去,把数字与数字的下标对应起来,到时候再打印下标。如果有多个相同的数字,但没有办法,无论如何对到新数组的下标都只有一个,因此,桶排序算法有去重的功能 

3.  以后一旦在代码里面看到字符char类型的,眼睛里面默认就要把它想象成ASCII码,就是整形

数组多数元素(众数)的查找 

(排序法,随机法,分治递归法,摩尔投票法)

题目链接:https://leetcode.cn/problems/majority-element/ 

题目:

代码1:

int majorityElement(int* nums, int numsSize)
{
    int i=0;
    int j=0;
    for (i=0;i<numsSize-1;i++)
    {
        for (j=0;j<=(numsSize-(i+2));j++)
        {
            if (*(nums+j)>*(nums+j+1))
            {
                int tmp=*(nums+j);
                *(nums+j)=*(nums+j+1);
                *(nums+j+1)=tmp;
            }
        }
    }
    return *(nums+(numsSize/2));
}

经验总结:

1. 如果将数组所有元素先单调递增或者单调递减排序,发现排序后的数组的下标为n/2的那个元素一定是众数。
2. 有时候在解题目的时候,可以对那个无序数组先进行排序,这样就可能可以使某些特征展现在新的有序数组里面。

代码2:

#include <stdlib.h>
#include <time.h>
int majorityElement(int* nums, int numsSize)
{
    srand((unsigned int)time(NULL));
    while(1)
    {
        int a = rand()%numsSize;
        int count=0;
        int i=0;
        for (i=0;i<numsSize;i++)
        {
            if (*(nums+a)==*(nums+i))
            {
                count++;
            }
        }
        if (count>numsSize/2)
        {
            return *(nums+a);
        }
    }
}

经验总结:

这也不失为一种方法 

代码3:

int majorityElement(int* nums, int numsSize)
{
    if (numsSize>=2)
    {
        int a=majorityElement(nums,numsSize/2);
        int b=majorityElement(nums+numsSize/2,numsSize-numsSize/2);
        if (a==b)
        {
            return a;
        }
        else
        {
            int i=0;
            int count_a=0;
            for (i=0;i<numsSize;i++)
            {
                if (*(nums+i)==a)
                {
                    count_a++;
                }
            }
            return count_a>numsSize/2?a:b;
        }
    }
    else
    {
        return *nums;
    }
}

经验总结:

1. 分治即“分而治之”,

     1. “分”指的是将一个大而复杂的问题划分成多个性质相同但是规模更小的子问题。

     2. 子问题继续按照这样划分,直到问题可以被轻易解决。

     3. “治”指的是将子问题单独进行处理。经过分治后的子问题,需要将解进行合并才能得到原问题的解,因此整个分治过程经常用递归来实现。

2. 递归我们是学过的。

       1. 明确这个函数的功能,有时候功能是返回东西,有时候是进行某个操作(如打印等等)

       2. 明确整个过程,并且分拆过程,其中某个过程必须得是与母过程性质结构类型一模一样。

       3. 在使用函数递归的时候,最好是能够求出像数列的递推公式一样的这么一个表达式。

       4. 回顾整个过程,添加限制条件,限制条件最好是控制那个与母过程一模一样的子过程

3  要明白的是:如果a是数组的众数,那如果把数组分成两个部分,那么a至少是其中一部分的众数。这两个数组部分有各自的众数,如果它们相等,那把这个数就是数组的众数,如果不相等的话,那么就去判断其中一个看是不是。   

代码4:

int majorityElement(int* nums, int numsSize)
{
    int force=0;
    int people=0;
    int i=0;
    for (i=0;i<numsSize;i++)
    {
        if (people==0)
        {
            force=*(nums+i);
            people+=1;
        }
        else if (*(nums+i)==force)
        {
            people+=1;
        }
        else
        {
            people-=1;
        }
    }
    return force;
}

经验总结:

求数组的众数时摩尔投票法是一个特别管用好使且新奇的方法lol

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/134560.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安全回顾总结

xss反射型漏洞复现 观察源码&#xff0c;可以看出源码中通过get传参到变量xss&#xff0c;并将一些特殊符号过滤了&#xff0c;则后续需要考虑该规则的绕过 echo “<img src”{$xss}">"; img标签 <img src“aaa” οnerrοr“alert(1)” 如果img图片不存在…

自然语言处理-01神经网络

数学和PY 向量是同时拥有大小和方向的量。向量可以表示为排成一排的数字集合&#xff0c;在 Python 实现中可以处理为一维数组。 向量和矩阵可以分别用一维数组和二维数组表示。另外&#xff0c;在矩阵中&#xff0c;将水平方向上的排列称为行&#xff08;row&#xff09;&…

2.SpringBoot-Condition

一、 参考 04-SpringBoot自动配置-切换内置web服务器_哔哩哔哩_bilibili 二、 Condition 顾名思义&#xff1a;条件。有点类似于if语句&#xff0c;只不过是通过注解的形式来实现。 以一个实际需求来学习该原理&#xff1a;有一个实体类User&#xff0c;想要创建该实例化对象…

Retrift

文章目录一、Retrift简介二、Retrift使用介绍三、注解1、GET2、POST3、PUT4、DELETE一、Retrift简介 retrift官网 1、是一个基于okhttp的网络请求框架 2、通过注解配置网络请求参数 3、图片链接和图片上传 4、支持同步和异步网络请求 5、支持多种数据的解析,提供对Rxjava的支…

光环:软件工程环境堆栈建设思路——徐磊

摘要&#xff1a;文章内容主要来源于光环国际2022年第三届中国科创者大会徐磊老师的分享&#xff0c;原分享名称为"企业开发者平台建设思路&#xff0c;云原生技术如何赋能开发者"。简述当前软件工程中Devops平台还缺少一个软件调试环境环节&#xff0c;这个环境其实…

stacking方法,boosting算法,与bagging的区别,adboost算法权重固定,regionboost权重动态学习

stacking方法&#xff0c;boosting算法&#xff0c;与bagging的区别&#xff0c;adboost算法权重固定&#xff0c;regionboost权重动态学习 提示&#xff1a;系列被面试官问的问题&#xff0c;我自己当时不会&#xff0c;所以下来自己复盘一下&#xff0c;认真学习和总结&#…

VBA之正则表达式(38)-- 提取规格数据(1/2)

实例需求&#xff1a;A列为某产品名称&#xff0c;现需要提取其中的规格数据&#xff0c;具体规则如下&#xff1a; 规格数据以如下关键字开头&#xff1a;RO、RE、SQ、SD、QD、OB、HX、ET、QR、D2规则数据可能有多段&#xff08;截图中红色部分&#xff09;提取规格数据之后&…

数据模拟:利用Java模拟数据(姓名,邮箱,地址,电话等信息,时间,工资,1-10随机数)并存入mysql

学大数据分析的同学们在做数据分析时一般很难找到适合数据集&#xff0c;本文就来分享一下如何利用Java模拟数据&#xff0c;并将产生数据保存至mysql数据库中。 主要技术就是Java产生数据&#xff0c;利用mybatis存入mysql数据库 数据模拟项目1.数据库建表2.构建maven项目3.项…

初级指针【一】

指针是什么&#xff1f;2个要点&#xff1a;指针是内存中一个最小单元编号&#xff0c;也就是地址。平时口语中说的指针&#xff0c;通常指的是指针变量&#xff0c;是用来存放地址的变量。总结&#xff1a;指针就是地址&#xff0c;我们口语中说的指针指的是指针变量。指针的大…

ZooKeeper分布式协调服务(节点分类、事件监听、java集成)

文章目录前言安装启动相关概念操作节点事件监听java客户端前言 ZooKeeper是一个分布式的&#xff0c;开放源码的分布式应用程序协调服务&#xff0c;是Google的Chubby一个开源的实现&#xff0c;是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件&#xf…

序列化二叉树 - 剑指Offer困难

序列化二叉树 题目链接 请实现两个函数&#xff0c;分别用来序列化和反序列化二叉树。 你需要设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑&#xff0c;你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为…

Alibaba Clould Tookit插件-IDEA实现一键部署

Alibaba Clould Tookit插件-IDEA实现一键部署 文章目录 前言说明使用 安装插件配置服务添加服务配置打包上传等内容 配置自动化配置命令配置文件上传前执行的命令 远程发布查看是否成功注意脚本 前言 本来一直使用jenkins后来坏掉了&#xff0c;别问&#xff0c;问就是老板…

(三分钟了解)处理外点(粗差)的方法--ransac和M估计

​ 编辑 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 外点也即是我们所说的粗差&#xff0c;是因为在实际工程当中由于人为因素或者测量设备等因素造成的测量值与实际情况相比误差较大。然后从高斯分布的角度来说就是大于3σ以外的数据。本篇博客将…

STM32——OLED调试工具与显示屏

文章目录一、调试工具二、OLED简介三、硬件电路接线图四、OLED驱动函数五、源码OLED.cOLED.hOLED_Font.h一、调试工具 调试方式 串口调试&#xff1a;通过串口通信&#xff0c;将调试信息发送到电脑端&#xff0c;电脑使用串口助手显示调试信息 显示屏调试&#xff1a;直接将…

ip综合实验

目录实验要求分析开始实施1&#xff0c;前期工作2&#xff0c;缺省路由配置3&#xff0c;hdlc封装4&#xff0c;ppp封装的pap认证5&#xff0c;ppp封装的chap认证6&#xff0c;构建MGRE环境nhrp协议7&#xff0c;RIP使内网互通水平分割关闭实验要求分析 1&#xff0c;如图为实…

2023前端二面高频vue面试题集锦

vuex是什么&#xff1f;怎么使用&#xff1f;哪种功能场景使用它&#xff1f; Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。vuex 就是一个仓库&#xff0c;仓库里放了很多对象。其中 state 就是数据源存放地&#xff0c;对应于一般 vue 对象里面的 data 里面存放的数据…

Js es6 Promise理解和使用

js中的promise是一个异步编程的解决方案&#xff0c;语法层面上他是一个构造函数&#xff0c;名字为Promise()。 它的作用就是将一个任务task封装为一个Promise类的实例对象&#xff0c;这个对象会将任务自动运行并得到任务结果&#xff0c;而且在得到结果的过程中并不会影响到…

告诉你应该选择 openSUSE 的五大理由

导读多数的的桌面 Linux 用户都会选择三种发行版本&#xff1a;Debian/Ubuntu、Fedora 或者 Arch Linux。但是今天&#xff0c;我将给出你需要使用 openSUSE 的五大理由。相比其他的 Linux 发行版&#xff0c;我总能在 openSUSE 上看到一些令人耳目一新的东西。我说不太好&…

多普勒效应(CSDN_0003_20220909)

目录 1. 机械波的多普勒效应 2. 电磁波的多普勒效应 文章编号&#xff08;CSDN_0003_20220909&#xff09; 由于原文公式较多&#xff0c;所以本文部分内容以截图的形式分享给大家&#xff0c;如果需要电子版原文&#xff0c;可留言或私信。 但凡提高雷达原理和雷达信号处理&a…

【前端】Vue项目:旅游App-(2)TabBar:搭建TabBar、循环获取动态数据、相关工具封装

文章目录目标代码与过程静态htmlcss改成动态数据效果总代码修改或新建的文件tabbarData.jstab-bar.vueload_assetsApp.vue目标 有两种实现方式&#xff1a; 把数据写死&#xff08;静态、直接写在html中&#xff09;动态数据&#xff1a;封装、vite获取动态数据方法 代码与过…