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

题目

在这里插入图片描述
题目链接:
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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot 调用外部接口的几种方式

Spring Boot 调用外部接口的几种方式 在微服务架构中&#xff0c;服务间的调用是不可或缺的环节。Spring Boot 为开发者提供了多种方式来实现这一任务&#xff0c;这个文章将为你详细介绍这些方式。 一、使用RestTemplate RestTemplate是 Spring Boot 早期版本中常用的 REST 客…

头歌C语言数据结构(队列的应用)

第1关&#xff1a;循环队列 任务描述 本关任务&#xff1a;编写一个循环队列&#xff0c;实现入队、出队操作&#xff0c;判断队空、队满等特殊情况。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.循环队列定义&#xff0c;2.入队、出队的定义&#xff…

Vue3路由及登录注销功能、设置导航守护功能模块

路由 在vue中&#xff0c;页面和组件都是.vue文件&#xff0c;可以说是一样的&#xff0c;结构、内容和生产方法都是一样&#xff0c;但是组件可以被反复使用&#xff0c;但页面一般只被使用一次。 路由的作用就是网页地址发生变化时&#xff0c;在App.vue页面的指定位置可以加…

【数据结构】双向循环链表专题解析

实现自己既定的目标&#xff0c;必须能耐得住寂寞单干。&#x1f493;&#x1f493;&#x1f493; 目录 •✨说在前面 &#x1f34b;知识点一&#xff1a;双向链表的结构 • &#x1f330;1."哨兵位"节点 • &#x1f330;2.双向带头循环链表的结构 &#x1f34b;…

[C#] 使用HttpClient请求https地址报错的解决方案

当使用HttpClient请求HTTPS地址遇到报错时&#xff0c;下面将解析并提供可能的解决方案供参考。 文章目录 异常代码无法定位错误的准确定位错误的 常见错误错误1错误2 解决问题生产环境开发环境 异常代码 首先&#xff0c;需要查看引发异常的代码部分, 无法定位错误的 以下代…

《完美黑暗》重启版6月发布,分析指出开发“没有问题” 状况没那么

易采游戏网5月12日消息&#xff0c;在21世纪初的游戏界&#xff0c;一款名为《完美黑暗》的FPS游戏在N64平台上崭露头角&#xff0c;以其独特的剧情设定和丰富的武器系统赢得了众多玩家的喜爱。然而&#xff0c;这款作品在推出时也并非一帆风顺&#xff0c;受到了不少玩家的吐槽…

C++ | Leetcode C++题解之第77题组合

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> temp;vector<vector<int>> ans;vector<vector<int>> combine(int n, int k) {// 初始化// 将 temp 中 [0, k - 1] 每个位置 i 设置为 i 1&#xff0c;即 [0, k - 1] 存…

springcloud整合网关(springcloud-gateway) 跨域处理

pom引入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!-- 服务注册 --><dependency><groupId>com.alibaba.cloud</groupId&…

使用Pandas对Data列进行基于顺序的分组排列

目录 一、引言 二、Pandas库简介 三、按照数据列中元素出现的先后顺序进行分组排列 四、案例分析 五、技术细节探讨与扩展应用 1. 技术细节 2. 扩展应用 3. 示例代码&#xff1a;用户行为分析 4. 进阶应用&#xff1a;分组后的聚合操作 5. 分组后的数据筛选 6. 分组…

【算法】滑动窗口——找到字符串中所有字母异位词

本节博客是对题目——找到字符串中所有字母异位词的从读题到代码实现以及优化的详细解读&#xff0c;有需要借鉴即可。 目录 1.题目2.滑动窗口 哈希数组3.异位词优化4.总结 1.题目 题目链接&#xff1a;LINK 首先来解释一下什么是异位词&#xff0c;所谓“异位词”&#xf…

JavaWeb文件上传/下载(Servlet)

效果 文件下载 文件上传 项目概述 Jakarta EE9&#xff0c;Web项目 项目文件结构 0 maven依赖&#xff0c;资源文件 <!-- lombok插件--> <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId&g…

最新的云渲染100活动有哪些?渲染100邀请码1a12

随着科技的进步&#xff0c;云渲染已经成为设计行业的必备工具&#xff0c;各个云渲染平台为了吸引用户也推出各种各样的活动&#xff0c;今天我们以广受好评的渲染100为例&#xff0c;来说下它们的活动体系。 1、新用户活动 渲染100对新用户很友好&#xff0c;提供了充足的测…

欢乐钓鱼大师攻略,怎么获取道具?

在《欢乐钓鱼大师》的游戏世界中&#xff0c;道具是提升钓鱼体验、解锁新功能以及完成挑战的关键。通过多种方式获取道具&#xff0c;能够帮助玩家更好地探索游戏世界、挑战自我&#xff0c;以及与其他玩家展开竞争。以下是关于如何获取道具的详细攻略&#xff0c;让你能够在游…

AI写作推荐-写文ai-AI在线写作生成器-3步完成写作任务

AI写作利器&#xff1a;推荐几款神助攻文案创作工具 随着技术的进步&#xff0c;人工智能&#xff08;AI&#xff09;已达到高级水平&#xff0c;在众多领域展现其强大能力。 在文本创作的领域&#xff0c;人工智能&#xff08;AI&#xff09;应用已显著地提升了写作效率和创意…

Java后端实现对象与文件接收数据(minio测试)

实现思路&#xff1a; 1. 两个接口实现&#xff0c;一个接对象数据(file)&#xff0c;一个接文件数据(json)。 2. json对象(base64String) 实体类信息 &#xff0c;请求体统一接收 3. file, String name ,String password ,String name &#xff0c; Controller层接收 统一…

环形链表(给定一个链表的头节点 head ,返回链表开始入环的第一个节点)的原理讲解

一&#xff1a;题目 二&#xff1a;原理讲解 解决这个题目 &#xff0c;我们得先理解它的原理。 1&#xff1a; 首先假设两个指针&#xff0c;一个快指针fast&#xff0c;一个慢指针slow&#xff0c;fast一次移动两个节点&#xff0c;slow一次移动一个节点。&#xff08;前面…

MF自定义控件方法

在MFC中&#xff0c;您可以通过自定义控件来实现特定的用户界面元素或功能&#xff0c;以满足您的应用程序需求。自定义控件通常是从CWnd类派生的子类&#xff0c;您可以在其中重写绘制、处理事件等方法&#xff0c;以实现您想要的功能和外观。以下是一般步骤&#xff1a; 创建…

【Java】变量类型

类变量&#xff1a;独立于方法之外的变量&#xff0c;用static修饰实例变量&#xff1a;独立于方法之外的变量&#xff0c;不过没有static修饰局部变量&#xff1a;类的方法中的变量 示例1&#xff1a; public class test_A {static int a;//类变量(静态变量)String b;//实例…

【JAVA进阶篇教学】第十篇:Java中线程安全、锁讲解

博主打算从0-1讲解下java进阶篇教学&#xff0c;今天教学第十篇&#xff1a;Java中线程安全、锁讲解。 当涉及到多线程编程时&#xff0c;保证线程安全是至关重要的。线程安全意味着在多个线程访问共享资源时&#xff0c;不会发生数据错乱或不一致的情况。为了实现线程安全&am…

问题:幂等性 分布式session

web项目中请求线程到service层的时候远程调用服务之前是串行化执行每个任务都要get阻塞等待任务完成&#xff0c;举例当用户在购物车页面点击去结算就会请求后台toTrade请求获取订单确认的详情数据并渲染到订单详情页&#xff0c;现在在toTrade请求中使用异步任务编排Completab…