牛客NC74 数字在升序数组中出现的次数【中等 二分 提供Java,Go,PHP答案】

题目

在这里插入图片描述
题目链接:
https://www.nowcoder.com/practice/70610bf967994b22bb1c26f9ae901fa2?tpId=196&tqId=37106&rp=1&ru=/exam/oj&qru=/exam/oj&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E7%25AE%2597%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D196&difficulty=undefined&judgeStatus=undefined&tags=&title=

思路

 二分法:
 找出目标target在非降序数组中最左边第一次出现的位置left,
 找出目标target在非降序数组中最由边最后一次出现的位置right,
 结果是right-left+1

参考答案Java

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     *
     * @param nums int整型一维数组
     * @param k int整型
     * @return int整型
     */
    public int GetNumberOfK (int[] nums, int k) {
        if (nums == null || nums.length == 0) return 0;
        int left = left(nums, k);
        if (left == -1) return 0;
        int right = right(nums, k);
        //System.out.println(left);
        //System.out.println(right);
        //if (nums.length > 934) System.out.println(nums[922] + "   " + nums[923] + "," +
        //        nums[934] + " " + nums[935]);  //有个测试用例元素个数超过934个了
        //if(left ==-1) return 0;
        if (left == right) return 1;
        return right - left + 1;
    }

    //t在升序数组中第一次出现的位置
    public int left(int[] arr, int t) {
        int L = 0, R = arr.length - 1;
        while (L < R - 1) {
            int m = L + (R - L) / 2;
            if (arr[m] > t) {
                R = m;
            } else if (arr[m] < t) {
                L = m + 1;
            } else {
                R = m;
            }
        }

        if (L > 0 && arr[L - 1] == t) return L - 1;
        if (arr[L] == t) return L;
        if (L < arr.length - 1 && arr[L + 1] == t) return L + 1;
        return -1;
    }

    //t在升序数组中最后一次出现的位置
    public int right(int[] arr, int t) {
        int L = 0, R = arr.length - 1;
        while (L < R - 1) {
            int m = L + (R - L) / 2;
            if (arr[m] > t) {
                R = m - 1;
            } else if (arr[m] < t) {
                L = m;
            } else {
                L = m;
            }
        }
        if (R < arr.length - 1 && arr[R + 1] == t) return R + 1;
        if (arr[R] == t) return R;
        if (R > 0 && arr[R - 1] == t) return R - 1;
        return -1;
    }


}

参考答案Go

package main



/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 *
 * @param nums int整型一维数组
 * @param k int整型
 * @return int整型
 */
func GetNumberOfK(nums []int, k int) int {
	//二分
	if nums == nil || len(nums) == 0 {
		return 0
	}
	left := left(nums, k)
	right := right(nums, k)

	if left == -1 || right == -1 {
		return 0
	}

	return right - left + 1
}

// 目标元素k第一次出现的位置
func left(arr []int, k int) int {
	L := 0
	R := len(arr) - 1
	for L < R-1 {
		m := L + (R-L)/2
		if arr[m] > k {
			R = m
		} else if arr[m] < k {
			L = m + 1
		} else {
			R = m
		}
	}

	if L > 0 && arr[L-1] == k {
		return L - 1
	}

	if arr[L] == k {
		return L
	}

	if L < len(arr)-1 && arr[L+1] == k {
		return L + 1
	}
	return -1
}

// 目标元素k 最后一次出现的位置
func right(arr []int, k int) int {
	L := 0
	R := len(arr) - 1
	for L < R-1 {
		m := L + (R-L)/2
		if arr[m] > k {
			R = m - 1
		} else if arr[m] < k {
			L = m
		} else {
			L = m
		}
	}

	if R < len(arr)-1 && arr[R+1] == k {
		return R + 1
	}

	if arr[R] == k {
		return R
	}

	if R > 0 && arr[R-1] == k {
		return R - 1
	}

	return -1
}

参考答案PHP

<?php


/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param nums int整型一维数组 
 * @param k int整型 
 * @return int整型
 */
function GetNumberOfK( $nums ,  $k )
{
    if ($nums == null || count($nums) == 0)
        return 0;

    $left = left($nums, $k);
    $right = right($nums, $k);

    if ($left == -1 || $right == -1) return 0;

    return $right - $left + 1;
}

//目标元素k 第一次出现的位置
function left($arr, $k)
{
    $L = 0;
    $R = count($arr) - 1;

    while ($L < $R - 1) {
        $m = intval(($L + $R) / 2);
        if ($arr[$m] > $k) {
            $R = $m;
        } else if ($arr[$m] < $k) {
            $L = $m + 1;
        } else {
            $R = $m;
        }
    }

    if ($L > 0 && $arr[$L - 1] == $k) return $L - 1;
    if ($arr[$L] == $k) return $L;
    if ($L < count($arr) - 1 && $arr[$L + 1] == $k) return $L + 1;
    return -1;
}

//目标元素k 最后一次出现的位置
function right($arr, $k)
{
    $L = 0;
    $R = count($arr) - 1;
    while ($L < $R - 1) {
        $m = intval(($L + $R) / 2);
        if ($arr[$m] > $k) {
            $R = $m - 1;
        } else if ($arr[$m] < $k) {
            $L = $m;
        } else {
            $L = $m;
        }
    }

    if ($R < count($arr) - 1 && $arr[$R + 1] == $k) return $R + 1;
    if ($arr[$R] == $k) return $R;
    if ($R > 0 && $arr[$R - 1] == $k) return $R - 1;
    return -1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵长辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值