牛客NC404 最接近的K个元素【中等 二分查找+双指针 Java/Go/PHP】

news2024/12/30 2:27:35

题目

在这里插入图片描述
题目链接:
https://www.nowcoder.com/practice/b4d7edc45759453e9bc8ab71f0888e0f

知识点

	二分查找;找到第一个大于等于x的数的位置idx;
	然后从idx开始往两边扩展

Java代码

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param nums int整型ArrayList
     * @param k int整型
     * @param x int整型
     * @return int整型ArrayList
     */
    public ArrayList<Integer> closestElement (ArrayList<Integer> nums, int k,
            int x) {
        //二分+双指针
        int n = nums.size();
        int right = firstGt(nums, x);

        int left = right - 1;

        ArrayList<Integer> ans = new ArrayList<>();
        LinkedList<Integer> ll = new LinkedList<>();
        if (right == 0) {
            for (int i = 0; i < k ; i++) {
                ll.add(nums.get(i));
            }
        } else if (right == n - 1) {
            for (int i = n - 1 - k; i < n ; i++) {
                ll.add(nums.get(i));
            }
        } else {
            while (left >= 0 || right < n) {
                int diffleft = -1;
                int diffright = -1;

                if (left >= 0) {
                    diffleft = x - nums.get(left);
                }
                if (right < n) {
                    diffright = nums.get(right) - x;
                }

                if (diffleft != -1 && diffright != -1) {

                    if (diffleft <= diffright) {
                        ll.addFirst(nums.get(left--));
                    } else {
                        ll.addLast(nums.get(right++));
                    }

                } else if (diffleft != -1) {

                    ll.addFirst(nums.get(left--));
                } else if (diffright != -1) {

                    ll.addLast(nums.get(right++));
                }

                if (ll.size() == k)
                    break;
            }
        }

        return new ArrayList<>(ll);
    }

    //找到大于等于x的下标位置
    public int firstGt(ArrayList<Integer> nums, int x) {
        int n = nums.size();
        int left = 0;
        int right = n;
        while (left < right) {
            int m = left + (right - left) / 2;
            if (nums.get(m) > x) {
                right = m - 1;
            } else if (nums.get(m) < x) {
                left = m + 1;
            } else {
                return m;
            }
        }

        return left;
    }
}

Go代码

package main

//import "fmt"

/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 *
 * @param nums int整型一维数组
 * @param k int整型
 * @param x int整型
 * @return int整型一维数组
 */
func closestElement(nums []int, k int, x int) []int {
	//二分+双指针
	n := len(nums)
	right := firstGt(nums, x)

	arrleft := []int{}
	arrright := []int{}
	ans := []int{}

	if right == 0 {
		for i := 0; i < k; i++ {
			ans = append(ans, nums[i])
		}
	} else if right == n-1 {
		for i := n - 1 - k; i < n; i++ {
			ans = append(ans, nums[i])
		}
	} else {
		left := right - 1
		cnt := 0
		for left >= 0 || right < n {
			diffleft := -1
			diffright := -1

			if left >= 0 {
				diffleft = x - nums[left]
			}
			if right < n {
				diffright = nums[right] - x
			}

			if diffleft != -1 && diffright != -1 {
				if diffleft <= diffright {
					arrleft = append(arrleft, nums[left])
					left--
				} else {
					arrright = append(arrright, nums[right])
					right++
				}
			} else if diffleft != -1 {
				arrleft = append(arrleft, nums[left])
				left--
			} else if diffright != -1 {
				arrright = append(arrright, nums[right])
				right++
			}

			cnt++
			if cnt == k {
				for i := len(arrleft) - 1; i >= 0; i-- {
					ans = append(ans, arrleft[i])
				}
				for i := 0; i < len(arrright); i++ {
					ans = append(ans, arrright[i])
				}

				break
			}
		}
	}
	return ans
}

//找到大等于x的位置
func firstGt(nums []int, x int) int {
	n := len(nums)
	left := 0
	right := n - 1

	for left < right {
		m := left + (right-left)/2

		if nums[m] > x {
			right = m - 1
		} else if nums[m] < x {
			left = m + 1
		} else {
			return m
		}
	}

	return left
}

PHP代码

<?php


/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param nums int整型一维数组 
 * @param k int整型 
 * @param x int整型 
 * @return int整型一维数组
 */
function closestElement( $nums ,  $k ,  $x )
{
      // 二分+双指针
    $n = count($nums);
    $right = firstGt($nums,$x);

    $ans = [];
    $arrleft=[];
    $arrright =[];

    if($right ==0 ){
        for($i=0;$i<$k;$i++){
            $ans[$i] = $nums[$i];
        }
    }else if($right ==$n-1){
        for($i=$n-1-$k;$i>=0;$i++){
            $ans[count($ans)] = $nums[$i];
        }
    }else {
        $left = $right-1;
        $cnt =0;
        while ($left>=0 || $right < $n){
            $diffleft=-1;
            $diffright =-1;

            if($left>=0) {
                $diffleft = $x-$nums[$left];
            }

            if($right<$n){
                $diffright = $nums[$right]-$x;
            }

            if($diffleft!=-1 && $diffright!=-1){
                if($diffleft<=$diffright){
                    $arrleft[count($arrleft)] = $nums[$left--];
                }else{
                    $arrright[count($arrright)] = $nums[$right++];
                }

            }else if($diffleft!=-1){
                $arrleft[count($arrleft)] = $nums[$left--];
            }else if($diffright!=-1){
                $arrright[count($arrright)] = $nums[$right++];
            }

            $cnt++;
            if($cnt==$k){
                for($i=count($arrleft)-1;$i>=0;$i--){
                    $ans[count($ans)] = $arrleft[$i];
                }
                for($i=0;$i<count($arrright);$i++){
                    $ans[count($ans)] = $arrright[$i];
                }

                break;
            }
        }
    }

    return $ans;
}


//找到大于等于x的位置
function firstGt($nums,$x){
    $n = count($nums);
    $left =0;
    $right = $n;
    while ($left<$right){
        $m = $left+(($right-$left)>> 1);
        if($nums[$m] > $x){
            $right = $m-1;
        }else if($nums[$m] < $x){
            $left = $m+1;
        }else{
            return $m;
        }
    }
    return $left;
}

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

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

相关文章

10分钟了解Golang泛型

泛型是Golang在1.18版本引入的强大工具&#xff0c;能够帮助我们在合适的场合实现简洁、可读、可维护的代码。原文: Go Generics: Everything You Need To Know 导言 可能有人会觉得Go泛型很难&#xff0c;因此想要借鉴其他语言&#xff08;比如Java、NodeJS&#xff09;的泛型…

timerfd加epoll封装定时器

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1、用timerfd加epoll封装定时器的优点2、代码实现 1、用timerfd加epoll封装定时器的优点 定时器为什么需要timerfd 在设计定时器时&#xff0c;我们首先想到的就是…

临近空间相关概念

临近空间概念 距地 20KM-100KM 的临近空间位于内外层空间之中&#xff0c;也称为 超高空、近空间、亚轨道等。 特点就是&#xff1a;纵跨 非电离层和电离层、空气稀薄&#xff0c;存在 臭氧、紫外、辐射等特殊环境 存在 重力波、行星波、大气放电等特殊现象。 临近空间高速飞…

YOLOv8+CLIP实现图文特征匹配

本文通过结合YOLOv8s的高效物体检测能力与CLIP的先进图像-文本匹配技术&#xff0c;展示了深度学习在处理和分析复杂多模态数据中的潜力。这种技术的应用不仅限于学术研究&#xff0c;还能广泛应用于工业、商业和日常技术产品中&#xff0c;以实现更智能的人机交互和信息处理。…

[BJDCTF2020]ZJCTF,不过如此 1

涉及&#xff1a;php的伪协议、preg_replace函数的漏洞和正则表达式的运用。 解题步骤 <?phperror_reporting(0); $text $_GET["text"]; $file $_GET["file"]; if(isset($text)&&(file_get_contents($text,r)"I have a dream"))…

璩静霸道言论引发百度风波随笔

从5月9日晚开始有关“百度副总裁璩静已从公司离职”的消息&#xff0c;仅两天时间就几乎布满互联网所有知名自媒体平台&#xff0c;可谓兹事体大&#xff0c;无异于互联网发生了一场八级地震&#xff0c;波及面之广&#xff0c;匪夷所思&#xff01; 百度截图 尽管笔者一直密切…

|Python新手小白中级教程|第二十八章:面向对象编程(类定义语法私有属性类的继承与多态)(4)

文章目录 前言一、类定义语法二、私有方法和私有属性1.私有属性2.私有方法 三、类“继承”1.初识继承2.使用super函数调用父类中构造的东西 四、类“多态”1.多态基础2.子类不同形态3.使用isinstance函数与多态结合判断类型 总结 前言 大家好&#xff0c;我是BoBo仔吖&#xf…

Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV

OpenCV是大型的Third party 计算机视觉库&#xff0c;在开发中会经常用到&#xff0c;本篇记录一下 在Ubuntu系统上安装和配置OpenCV&#xff0c;并使用C/C调用OpenCV 关于VS Code配置C/C开发环境的部分&#xff0c;见之前的博文 Linux/Ubuntu系统下使用VS Code配置C/C开发环境…

动态规划算法练习——计数问题

题目描述 给定两个整数 a 和 b&#xff0c;求 a 和 b 之间的所有数字中 0∼9 的出现次数。 例如&#xff0c;a1024&#xff0c;b1032&#xff0c;则 a 和 b 之间共有 9 个数如下&#xff1a; 1024 1025 1026 1027 1028 1029 1030 1031 1032 其中 0 出现 10 次&#xff0c;1 出现…

360度全景航拍生成原创,玩命增粉10W ,月入万余元【视频教学 配套设施专用工具】

抖音近期推出了一种全新的玩法&#xff0c;那就是360度全景航拍&#xff0c;这为原创者们带来了新的增粉机会&#xff0c;有望在一个月内收入过万。这个新玩法配有视频教学和专用工具。 项目 地 址 &#xff1a; laoa1.cn/1993.html 抖音的这个新功能&#xff0c;就是360度全…

南京观海微电子----开关电流与输入输出电流的关系

BOOST 结构的工作原理及波形 BOOST 结构简单原理图见图 1&#xff0c;工作时各点的电压电流波形见图 2。 不考虑上电时的情形&#xff0c;仅考虑稳定工作时&#xff0c;情况如下&#xff1a; 当开关管 Q 导通时&#xff08;开关管电压为 0&#xff09;&#xff0c;电感 L 相当…

【密评】 | 商用密码应用安全性评估从业人员考核题库(9/58)

Hill密码是重要古典密码之一&#xff0c;其加密的核心思想的是&#xff08;&#xff09;。 A.线性变换 B.非线性变换 C.循环移位 D.移位 著名的Kerckhoff原则是指&#xff08;&#xff09;。 A.系统的保密性不但依赖于对加密体制或算法的保密&#xff0c;而且依赖于密钥 B.系统…

【计算机网络】数据链路层的功能

数据链路层的基本功能&#xff1a; 封装成帧透明传输差错检测 数据链路层使用的信道主要有两种 点对点信道——PPP协议广播信道——CSMA/CD协议(有线局域网)、CSMA/CA协议(无线局域网) 数据链路层所处的地位 从图中可以看出&#xff0c;数据从主机H1送到主机H2需要在路径中…

C#【进阶】泛型

1、泛型 文章目录 1、泛型1、泛型是什么2、泛型分类3、泛型类和接口4、泛型方法5、泛型的作用思考 泛型方法判断类型 2、泛型约束1、什么是泛型2、各泛型约束3、约束的组合使用4、多个泛型有约束思考1 泛型实现单例模式思考2 ArrayList泛型实现增删查改 1、泛型是什么 泛型实现…

Autoxjs 实践-Spring Boot 集成 WebSocket

概述 最近弄了福袋工具&#xff0c;由于工具运行中&#xff0c;不好查看福袋结果&#xff0c;所以我想将福袋工具运行数据返回到后台&#xff0c;做数据统计、之后工具会越来越多&#xff0c;就弄了个后台&#xff0c;方便管理。 实现效果 WebSocket&#xff1f; websocket是…

【JavaEE初阶系列】——Cookie和Session应用之实现登录页面

目录 &#x1f6a9;本章目标 1.登录页面 2.servlet处理上述的登录请求 3.网站主页(成功登录之后的页面&#xff09; &#x1f6a9;实现过程 &#x1f393;登录页面 &#x1f393;Servlet处理登录请求 &#x1f388;获取请求传来的参数(用户名和密码) &#x1f388;验证…

Electron学习笔记(五)

文章目录 相关笔记笔记说明 七、系统1、系统对话框2、自定义窗口菜单3、系统右键菜单4、快捷键(1)、监听网页按键事件 &#xff08;窗口需处于激活状态&#xff09;(2)、监听全局按键事件 &#xff08;窗口无需处于激活状态&#xff09;(3)、补充&#xff1a;自定义窗口菜单快捷…

Three.js基础练习——渲染一个立方体

1.学习内容参考了 three.js入门教程--零基础也能学会_threejs菜鸟教程-CSDN博客 本章内容包含渲染立方体&#xff0c;并配合ui工具食用~ 2.效果图 import * as THREE from three import * as dat from dat.gui import { OrbitControls } from three/addons/controls/OrbitC…

【网站项目】SpringBoot803房屋租赁管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

【Golang】VSCode进行GO的调试

原来的launch.json {"version": "0.2.0","configurations": [{"name": "Golang","type": "go","request": "launch","program": "${workspaceFolder}","…