yo!这里是常见问题的特殊(大佬)解法-总结

2023-11-05 16:20

本文主要是介绍yo!这里是常见问题的特殊(大佬)解法-总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

前言

常见问题

最大公约数

1.问题介绍

2.解决方法

不创建临时变量交换两个变量的值

1.问题介绍

2.解决方法

求二进制中1的个数

1.问题介绍

2.解决方法

左旋字符串

1.问题介绍

2.解决方法

 更新中......


前言

       在一些常见的笔试面试的题目求解方法中,除了比较容易想到(暴力)的方法之外,还有非常不容易想到的方法,那这些方法呢,在一些中小厂笔试或面试环节(大厂大部分都是原创题)过程中,面试官会想要听到。比如,问你一个问题之后,你可能就问题阐述了一个直接想得到的方法,但是面试官下一步就会问你有无更加优化的方法,那么此时你可以通过在此文的学习后能够回答出面试官的进一步加问,让面试官眼前一亮。

       这是一个长期积累的过程,我也只是整理了一部分,在后续的学习中,我会更新更多,那么大家也可以在评论区讨论甚至更优的方法以及其他问题的特殊方法,我看到也会整理到文章其中,供大家参考学习与交流。

       希望大家不要只看一遍就觉得自己会了,也不是死记硬背,而一定要去反复的理解思路过程,周期性的回来复习一下,那么久而久之,量变就会引起质变。加油!

常见问题

  • 最大公约数

1.问题介绍

       求出两个数的最大公约数,如果有一个自然数a能被自然数b整除,则称a为b的倍数,b为a的约数。几个自然数公有的约数,叫做这几个自然数的公约数。公约数中最大的一个公约数,称为这几个自然数的最大公约数。

2.解决方法

       这里不再介绍穷举法等比较暴力的方法,说一下辗转相除法

思路过程:

       需求最大公约数的两个数赋给a、b,将a%b赋给m,之后,将b赋给a,m赋给b,再a%b赋给m,循环直到m为0,此时最大公约数为b的值。比如,

        代码:

int main()
{int a = 0,b = 0,m = 0;scanf("%d %d",&a,&b);m = a%b;while (m){a = b;b = m;m = a%b;}printf("最大公约数为%d\n",b);return 0;
}

 测试:

ps:有老铁可能会说a%b的话,一定要a放较大数,b放较小数,其实并不需要,看图

       这里提一嘴最小公倍数,在算出最大公约数之后,最小公倍数就是最初的a乘以b除以最大公约数,代码:

//_a和_b为最初的需求最大公约数的两个数,b为最大公约数
printf("最小公倍数为%d\n",_a*_b/b);

测试:

 


  • 不创建临时变量交换两个变量的值

1.问题介绍

       “交换两个变量的值???就这!有手就行,看我随随便便int tmp=x;x=y;y=tmp; 啊......不创建临时变量。”这应该是每个小白的内心戏了吧哈哈,对没看错,不能创建临时变量交换两个变量的值。

2.解决方法

       不创建临时变量交换两个变量的值,其实方法也有很多,在这里介绍一下异或法吧,先说一下什么是异或,异或是按位异或,是一种操作符,位指的是二进制数,口诀:相同为0,不同为1。

思路过程:

       1.异或的特点:有任意数,

①a^0=0;   

②a^a=0;   

③满足交换律,

根据这些特点,大家去看这样一个例子:1^2^3^2^1=1^1^2^2^3=3,有没有感觉对异或有了一个新的认知呢。

       2.见下方代码,核心部分为①x = x^y;   ②y = x^y;   ③x = x^y; ,

经①,x中存放的是x^y,此时②就变成了y=x^y^y,

经②,y中存放的是原先的x,x中依旧是x^y,此时③就变成了x=x^y^x,

经③,x的值是是原先的y,

所以,经过核心部分,x、y的值就发生了交换。

代码:

int main()
{int x = 3;int y = 5;printf("交换前:\n");printf("%d %d\n",x,y);x = x^y;y = x^y;x = x^y;printf("交换后:\n");printf("%d %d\n", x, y);return 0;
}

测试:

 ps:异或法很巧妙,但存在缺点,就是只能交换两个整数的值,因为异或只能作用于整数,所以建议遇到需要交换两个变量的值时,还是使用临时变量的方法,即简单又快捷又不挑作用数据类型。

 


  • 求二进制中1的个数

1.问题介绍

       求二进制中1的个数,这是对于整数而言的,因为我们知道整数在计算机中是以补码的形式存在的,这里就是说,给定一个整数,需给出这个整数的补码的二进制中1的个数,比如,

①整数3,补码的二进制:000000000000000000000000 0000 0011,1的个数为2;

②整数13,补码的二进制:0000000000000000000000 0000 1101,1的个数为1;

③整数-1,补码的二进制:11111111111111111111111111111111,1的个数为32,

所以,我们就要用程序来实现这样的一个功能。

2.解决方法

       第一种方法,是大家相对容易想到的方法,就是利用按位右移符>>及按位与&的特点。

思路过程:

       在学习过按位与和按位或的知识点之后,容易了解到:

①一个二进制数 & 1 之后不变,& 0之后变0;

②一个二进制数 | 0之后不变,| 1之后变1,

所以给我们一个数,将其 & 1之后,就能得到这个数的二进制形式的最后一位数字,再按位右移>>1,再 & 1循环往复32次,就能得到二进制中1的个数。

例如:

整数5(补码为000000000000000000000000 0000 0101),

①按位与1(补码为000000000000000000000000 0000 0001),得到补码000000000000000000000000 0000 0001,即整数1,得到二进制的最后一位是1,

此时,将5>>1,得到补码000000000000000000000000 0000 0010,

②再按位与1,得到补码000000000000000000000000 0000 0000,即整数0,得到二进制倒数第二位为0,

③循环32次,就得到二进制数的每一位,同时用计数器count统计其中1的个数,得解。

代码:

int _1NumberOf1(int n) {int i = 0;int count = 0;while (i < 32){i++;if ((n & 1) == 1){count++;}n >>= 1;}return count;
}

       第二种方法,就是类比 “求得一个十进制整数的每一位数字” 这个问题的思路,当我们需要求得二进制整数的每一位数字,是不是也可以用相同的办法?

思路过程:

       我们先来看问题“求得一个十进制整数的每一位数字”,方法是,先%10,再 /10,循环直到这个数为0停止,期间通过输出%10之后的数字就是十进制整数的每一位数字,那类比到二进制整数,是不是也可以得到二进制整数的每一位数字呢,答案是可以的。

代码:

int _2NumberOf1(int n)
{int count = 0;unsigned int m = n;while (m){if (m % 2 == 1)count++;m /= 2;}return count;
}

       第三种方法,相对于上面两种方法是非常难以想到的方法,也呼应了笔者写这篇文章的初衷。

思路过程:

       借助n=n&(n-1)的巧妙之处,举个栗子:

整数n为13,二进制为1101,此时n-1的二进制为1100,

①按位与之后得到1100再赋给n,此时n-1为1011,

②按位与之后得到1000赋给n,此时n-1为0111,

③按位与之后得到0000赋给n,

我们可以看到n为0之前进行了三次按位与,而且原始的n的二进制中1的个数就是3,这是巧合吗,no,是巧妙,举多个栗子之后就会发现n=n&(n-1)的执行次数就是n的二进制中1的个数。

代码:

int _3NumberOf1(int n)
{int count = 0;while (n){n = n & (n - 1);count++;}return count;
}

三种方法的测试:

 


  • 左旋字符串

1.问题介绍

        左旋字符串,顾名思义,向左旋转字符串的k个字符位,比如,字符串位"abcdef",要求左旋四个字符位,即"efabcd",左旋8个字符位,即"cdefab"。

2.解决方法

        小伙伴们看到这个题目,应该会想到这种方法:保存第一个字符,将后面的所有字符向前移,循环k次即可,我想大家按照这个思路写出程序不是问题,但是我想介绍一种借助反转字符串的方法。

思路过程:

       反转字符串:将字符串颠倒存放,比如,字符串"abcd",反转之后变成"dcba",现要求左旋字符串的k个字符位,

①反转前k个字符组成的字符串;

②反转剩下的字符组成的字符串;

③反转整个字符串,

比如,有字符串"abcdef",左旋2个字符位,

①"ab"--->"ba";

②"cdef"--->"fedc";

③"bafedc"--->"cdefab",得解

代码:

//反转字符串
void reverse_str(char* left, char* right)
{while (left < right){char tmp = *left;*left = *right;*right = tmp;left++;right--;}
}
//左旋字符串
void LeftRotate_k2(char arr[], int k)
{int sz = strlen(arr);k %= sz;reverse_str(arr, arr + k - 1);reverse_str(arr + k, arr + sz - 1);reverse_str(arr, arr + sz - 1);
}
//ps:k%=sz;,是因为对于一个字符串,比如长度为4,左旋10个字符位就相当于左旋2个字符位

测试:

 


 更新中......

这篇关于yo!这里是常见问题的特殊(大佬)解法-总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/351038

相关文章

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta

Nginx 配置跨域的实现及常见问题解决

《Nginx配置跨域的实现及常见问题解决》本文主要介绍了Nginx配置跨域的实现及常见问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来... 目录1. 跨域1.1 同源策略1.2 跨域资源共享(CORS)2. Nginx 配置跨域的场景2.1

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用

Nginx Location映射规则总结归纳与最佳实践

《NginxLocation映射规则总结归纳与最佳实践》Nginx的location指令是配置请求路由的核心机制,其匹配规则直接影响请求的处理流程,下面给大家介绍NginxLocation映射规则... 目录一、Location匹配规则与优先级1. 匹配模式2. 优先级顺序3. 匹配示例二、Proxy_pa

Swagger在java中的运用及常见问题解决

《Swagger在java中的运用及常见问题解决》Swagger插件是一款深受Java开发者喜爱的工具,它在前后端分离的开发模式下发挥着重要作用,:本文主要介绍Swagger在java中的运用及常... 目录前言1. Swagger 的主要功能1.1 交互式 API 文档1.2 客户端 SDK 生成1.3

java连接opcua的常见问题及解决方法

《java连接opcua的常见问题及解决方法》本文将使用EclipseMilo作为示例库,演示如何在Java中使用匿名、用户名密码以及证书加密三种方式连接到OPCUA服务器,若需要使用其他SDK,原理... 目录一、前言二、准备工作三、匿名方式连接3.1 匿名方式简介3.2 示例代码四、用户名密码方式连接4

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

在Spring Boot中实现HTTPS加密通信及常见问题排查

《在SpringBoot中实现HTTPS加密通信及常见问题排查》HTTPS是HTTP的安全版本,通过SSL/TLS协议为通讯提供加密、身份验证和数据完整性保护,下面通过本文给大家介绍在SpringB... 目录一、HTTPS核心原理1.加密流程概述2.加密技术组合二、证书体系详解1、证书类型对比2. 证书获