当前位置:   article > 正文

二分查找(数据结构与算法java代码)_java算法题 二分查找

java算法题 二分查找

第一题 二分查找

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

  1. class Solution {
  2. public int search(int[] nums, int target) {
  3. int i = 0, j = nums.length - 1;
  4. while (i <= j) {
  5. int m = i + (j - i) /2;
  6. if (nums[m] < target) {
  7. i = m + 1;
  8. } else if (nums[m] > target) {
  9. j = m - 1;
  10. } else {
  11. return m;
  12. }
  13. }
  14. return -1;
  15. }
  16. }

第二题 搜索插入二分法(无重复元素)

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

  1. class Solution {
  2. public int searchInsert(int[] nums, int target) {
  3. int i = 0, j = nums.length - 1;
  4. while (i <= j) {
  5. int m = i + (j - i) / 2;
  6. if (nums[m] < target) {
  7. i = m + 1;
  8. } else if (nums[m] > target) {
  9. j = m - 1;
  10. } else {
  11. return m;
  12. }
  13. }
  14. return i;
  15. }
  16. }

第三题 在排序数组中查找元素的第一个和最后一个

给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。

如果数组中不存在目标值 target,返回 [-1, -1]

你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。

直接改代码

  1. class Solution {
  2. public int[] searchRange(int[] nums, int target) {
  3. int[] result = new int[2];
  4. int i = 0, j = nums.length - 1;
  5. // 查找左边界
  6. while (i <= j) {
  7. int m = i + (j - i) / 2;
  8. if (nums[m] < target) {
  9. i = m + 1;
  10. } else if (nums[m] > target) {
  11. j = m - 1;
  12. } else {
  13. j = m - 1;
  14. }
  15. }
  16. if (i == nums.length || nums[i] != target) {
  17. result[0] = -1;
  18. result[1] = -1;
  19. return result;
  20. } else {
  21. result[0] = i;
  22. }
  23. // 查找右边界
  24. i = 0;
  25. j = nums.length - 1;
  26. while (i <= j) {
  27. int m = i + (j - i) / 2;
  28. if (nums[m] < target) {
  29. i = m + 1;
  30. } else if (nums[m] > target) {
  31. j = m - 1;
  32. } else {
  33. i = m + 1;
  34. }
  35. }
  36. // 当输入为[1] 1时, i == nums.length
  37. if (nums[j] != target) {
  38. result[0] = -1;
  39. result[1] = -1;
  40. return result;
  41. } else {
  42. result[1] = j;
  43. }
  44. return result;
  45. }
  46. }

复用查找左边界

得先确认查找元素右边的离他最近的元素,无法确认时只能写target + 1,但这时又有两个问题,一是可能出现和target + 1重复的元素,导致无法通过nums[i] != target返回失败值-1,二是可能在返回-1时把-1的值改了

转化为查找元素

查找最左 -> target - 0.5,返回i

查找最右 -> target + 0.5,返回j

出现问题,得另外写代码确认所查找的元素是否存在,不然无法返回[-1, -1]

  1. class Solution {
  2. public static int searchLeftRange(int[] nums, double target) {
  3. int i = 0, j = nums.length - 1;
  4. while (i <= j) {
  5. int m = i + (j - i) / 2;
  6. if ((double)nums[m] < target) {
  7. i = m + 1;
  8. } else if ((double)nums[m] > target) {
  9. j = m - 1;
  10. } else {
  11. j = m - 1;
  12. }
  13. }
  14. if (i == nums.length) {
  15. return -1;
  16. } else {
  17. return i;
  18. }
  19. }
  20. public static int searchRightRange(int[] nums, double target) {
  21. int i = 0, j = nums.length - 1;
  22. while (i <= j) {
  23. int m = i + (j - i) / 2;
  24. if ((double)nums[m] < target) {
  25. i = m + 1;
  26. } else if ((double)nums[m] > target) {
  27. j = m - 1;
  28. } else {
  29. j = m - 1;
  30. }
  31. }
  32. if (i == nums.length) {
  33. return -1;
  34. } else {
  35. return j;
  36. }
  37. }
  38. public int[] searchRange(int[] nums, int target) {
  39. int[] result = {searchLeftRange(nums, (double)(target - 0.5)), searchRightRange(nums, (double)(target + 0.5))};
  40. return result;
  41. }
  42. }

第四题 求平方根

给你一个非负整数 x ,计算并返回 x 的 算术平方根 。

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。

注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5

自解

  1. class Solution {
  2. public int mySqrt(int x) {
  3. // 1, 0平方根为自身
  4. if (x <= 1) {
  5. return x;
  6. }
  7. // 2以上的数
  8. int i = 0, j = x / 2;// 最大为原数一半
  9. while (i <= j) {
  10. int m = i + (j - i) / 2;
  11. if ((long) m * m < x) { // 不强转会出错
  12. i = m + 1;
  13. } else if ((long) m * m > x) {
  14. j = m - 1;
  15. } else {
  16. return m;
  17. }
  18. }
  19. return j;
  20. }
  21. }

官解

  1. class Solution {
  2. public int mySqrt(int x) {
  3. int l = 0, r = x, ans = -1;
  4. while (l <= r) {
  5. int mid = l + (r - l) / 2;
  6. if ((long) mid * mid <= x) { // 平方小于等于x的的最大整数ans
  7. ans = mid;
  8. l = mid + 1;
  9. } else {
  10. r = mid - 1;
  11. }
  12. }
  13. return ans;
  14. }
  15. }

第五题 有效的完全平方根

给你一个正整数 num 。如果 num 是一个完全平方数,则返回 true ,否则返回 false 。

完全平方数 是一个可以写成某个整数的平方的整数。换句话说,它可以写成某个整数和自身的乘积。

不能使用任何内置的库函数,如  sqrt 。

  1. class Solution {
  2. public boolean isPerfectSquare(int num) {
  3. if (num == 1) {
  4. return true;
  5. }
  6. // 特殊 : 1
  7. int i = 0, j = num / 2;
  8. while (i <= j) {
  9. int m = i + (j - i) / 2;
  10. if ((long) m * m < num) {
  11. i = m + 1;
  12. } else if ((long) m * m > num) {
  13. j = m - 1;
  14. } else {
  15. return true;
  16. }
  17. }
  18. return false;
  19. }
  20. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/977706
推荐阅读
相关标签
  

闽ICP备14008679号