博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Golang面试考题记录 ━━ 两个数组的交集 II 双100%及goto、continue和break的用法
阅读量:4116 次
发布时间:2019-05-25

本文共 2539 字,大约阅读时间需要 8 分钟。

===问:

给定两个数组,编写一个函数来计算它们的交集。

示例 1:

输入: nums1 = [1,2,2,1], nums2 = [2,2]

输出: [2,2]

示例 2:

输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]

输出: [4,9]

说明:

  • 输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
  • 我们可以不考虑输出结果的顺序。

进阶:

  • 如果给定的数组已经排好序呢?你将如何优化你的算法?
  • 如果 nums1 的大小比 nums2 小很多,哪种方法更优?
  • 如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?

===答:

方法一:执行11.56%|90.44% ,内存94.59%

比较鸡贼,因为知道测试数据没有负数,因此用了负数替换,理论我想应该比append()快点吧~

func intersect1(nums1 []int, nums2 []int) []int {
numsA := nums1 numsB := nums2 if len(nums1) < len(nums2) {
numsA = nums2 numsB = nums1 } var r []int for _, v := range numsA {
for i, y := range numsB {
if v == y {
r = append(r, v) numsB[i] = -1 //退出一层 break } } } return r}

方法二:执行100.00%|90.44% ,内存100.00%|94.59%

看了一下内存排名第一的用了递归。。。

func intersect2(nums1 []int, nums2 []int) []int {
numsA := nums1 numsB := nums2 if len(nums1) < len(nums2) {
numsA = nums2 numsB = nums1 } var r []int for _, v := range numsA {
// 本局意义不大,系统发现numsB为空值亦不会循环 /*if len(numsB) == 0 { return r }*/ for i, y := range numsB {
if v == y {
r = append(r, v) //去除一个元素 numsB = append(numsB[:i], numsB[i+1:]...) //退出一层 break } } } return r}

===知识点

本题别的没什么好总结的,主要是一个知识点要强化一下,那就是breakcontinuegoto的用法

参考:

goto

goto语句可以无条件地转移到过程中指定的行。 通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。

在结构化程序设计中一般不主张使用goto语句, 以免造成程序流程的混乱
goto对应(标签)既可以定义在for循环前面,也可以定义在for循环后面,当跳转到标签地方时,继续执行标签下面的代码。

func goto1() {
// 放在for前面,此例会一直循环下去 Loop: fmt.Println("test") for a:=0;a<5;a++{
fmt.Println(a) if a>3{
goto Loop } }}func goto2() {
for a:=0;a<5;a++{
fmt.Println(a) if a>3{
goto Loop } } // 放在for后边,跳出结束 Loop: fmt.Println("test")}

break

在没有使用loop标签的时候break只是跳出了第一层for循环

使用标签后跳出到指定的标签,break只能跳出到之前,
如果将Loop标签放在后边则会报错
break标签只能用于for循环,跳出后不再执行标签对应的for循环

func breakTest() {
//正常执行Loop: for j := 0; j < 3; j++ {
// 出错 // Loop: fmt.Println(j) for a := 0; a < 5; a++ {
// 出错 // Loop: fmt.Println(a) if a > 3 {
// 出错 // Loop: break Loop } } }// 出错// Loop: fmt.Println("end")}/*输出:001234end*/

continue

continue就是直接进入下一次循环。break是跳出整个循环,标签的使用类似于break

// 只能放在这个位置,其余位置和break一样,皆出错loop:	for j := 0; j < 3; j++ {
fmt.Println(j) for a := 0; a < 5; a++ {
fmt.Println(a) if a > 3 {
continue loop } } } fmt.Println("end")/*输出:001234101234201234end*/

goto语句本身就是做跳转用的,而break和continue是配合for使用的。所以goto的使用不限于for,通常与条件语句配合使用

在for循环中break和continue可以配合标签使用。

转载地址:http://wtkpi.baihongyu.com/

你可能感兴趣的文章
数据结构之树
查看>>
数据结构之二叉树
查看>>
二叉树非递归遍历算法思悟
查看>>
红黑树算法思悟
查看>>
从山寨Spring中学习Spring IOC原理-自动装配注解
查看>>
实例区别BeanFactory和FactoryBean
查看>>
Spring后置处理器BeanPostProcessor的应用
查看>>
Spring框架的ImportSelector到底可以干嘛
查看>>
Mysql中下划线问题
查看>>
微信小程序中使用npm过程中提示:npm WARN saveError ENOENT: no such file or directory
查看>>
Xcode 11 报错,提示libstdc++.6 缺失,解决方案
查看>>
idea的安装以及简单使用
查看>>
Windows mysql 安装
查看>>
python循环语句与C语言的区别
查看>>
Vue项目中使用img图片和background背景图的使用方法
查看>>
vue 项目中图片选择路径位置static 或 assets区别
查看>>
vue项目打包后无法运行报错空白页面
查看>>
Vue 解决部署到服务器后或者build之后Element UI图标不显示问题(404错误)
查看>>
element-ui全局自定义主题
查看>>
facebook库runtime.js
查看>>