• Leetcode刷题167. 两数之和 II - 输入有序数组


    给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列  ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。

    以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。

    你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。

    你所设计的解决方案必须只使用常量级的额外空间。

     
    示例 1:

    输入:numbers = [2,7,11,15], target = 9
    输出:[1,2]
    解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。


    示例 2:

    输入:numbers = [2,3,4], target = 6
    输出:[1,3]
    解释:2 与 4 之和等于目标数 6 。因此 index1 = 1, index2 = 3 。返回 [1, 3] 。


    示例 3:

    输入:numbers = [-1,0], target = -1
    输出:[1,2]
    解释:-1 与 0 之和等于目标数 -1 。因此 index1 = 1, index2 = 2 。返回 [1, 2] 。
     

    提示:

    2 <= numbers.length <= 3 * 104
    -1000 <= numbers[i] <= 1000
    numbers 按 非递减顺序 排列
    -1000 <= target <= 1000
    仅存在一个有效答案

    来源:力扣(LeetCode)
    链接:https://leetcode.cn/problems/two-sum-ii-input-array-is-sorted
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    1. class Solution {
    2. public int[] twoSum(int[] numbers, int target) {
    3. // return twoSumI(numbers, target);
    4. // return twoSumII(numbers, target);
    5. // return twoSumIII(numbers, target);
    6. // return twoSumIIII(numbers, target);
    7. return twoSumIIIII(numbers, target);
    8. }
    9. //方法五:双指针 + 二分查找
    10. //时间复杂度O(N),空间复杂度O(1)
    11. private int[] twoSumIIIII(int[] numbers, int target) {
    12. if (numbers == null || numbers.length == 0) {
    13. return null;
    14. }
    15. int lo = 0, hi = numbers.length - 1;
    16. while (lo < hi) {
    17. int mid = lo + (hi - lo) / 2;
    18. if (numbers[lo] + numbers[mid] > target) {
    19. hi = mid - 1;
    20. } else if (numbers[hi] + numbers[mid] < target) {
    21. lo = mid + 1;
    22. } else if (numbers[lo] + numbers[hi] > target) {
    23. hi--;
    24. } else if (numbers[lo] + numbers[hi] < target) {
    25. lo++;
    26. } else {
    27. return new int[]{lo + 1, hi + 1};
    28. }
    29. }
    30. return null;
    31. }
    32. //方法四:二分查找,时间复杂度O(NlogN),空间复杂度O(1)
    33. private int[] twoSumIIII(int[] numbers, int target) {
    34. if (numbers == null || numbers.length == 0) {
    35. return new int[0];
    36. }
    37. for (int i = 0; i < numbers.length; i++) {
    38. int left = i + 1;
    39. int right = numbers.length - 1;
    40. int val = target - numbers[i];
    41. while (left <= right) {
    42. int mid = (right - left) / 2 + left;
    43. if (val < numbers[mid]) {
    44. right = mid - 1;
    45. } else if (val > numbers[mid]) {
    46. left = mid + 1;
    47. } else {
    48. return new int[] {i + 1, mid + 1};
    49. }
    50. }
    51. }
    52. return new int[0];
    53. }
    54. //方法三:使用Map缓存结果,时间复杂度O(N),空间复杂度O(N)
    55. private int[] twoSumIII(int[] numbers, int target) {
    56. if (numbers == null || numbers.length == 0) {
    57. return new int[0];
    58. }
    59. Map map = new HashMap<>();
    60. for (int i = 0; i < numbers.length; i++) {
    61. if (map.containsKey(numbers[i])) {
    62. return new int[]{map.get(numbers[i]) + 1, i + 1};
    63. }
    64. map.put(target - numbers[i], i);
    65. }
    66. return new int[0];
    67. }
    68. //方法二:双指针,lo指向数据头部,hi指向尾部,比较两指针相加的值与target大小,并移动指针
    69. //时间复杂度O(N),空间复杂度O(1)
    70. private int[] twoSumII(int[] numbers, int target) {
    71. if (numbers == null || numbers.length == 0) {
    72. return new int[0];
    73. }
    74. int lo = 0, hi = numbers.length - 1;
    75. while (lo < hi) {
    76. if (numbers[lo] + numbers[hi] > target) {
    77. hi--;
    78. } else if (numbers[lo] + numbers[hi] < target) {
    79. lo++;
    80. } else {
    81. return new int[]{lo + 1, hi + 1};
    82. }
    83. }
    84. return new int[0];
    85. }
    86. //方法一:暴力解法,两层for循环,时间复杂度O(N^2),空间复杂度O(1)
    87. private int[] twoSumI(int[] numbers, int target) {
    88. if (numbers == null || numbers.length == 0) {
    89. return new int[0];
    90. }
    91. for (int i = 0; i < numbers.length; i++) {
    92. for (int j = i + 1; j < numbers.length; j++) {
    93. if (numbers[i] + numbers[j] == target) {
    94. return new int[]{i + 1, j + 1};
    95. }
    96. }
    97. }
    98. return new int[0];
    99. }
    100. }

  • 相关阅读:
    网页中F5刷新与ctrl + F5强制刷新的区别?
    SQL sever中的存储过程
    最全Java中高级面试题汇总,全会月薪3W起
    uview的u-subsection分段器组件的使用
    大数据中间件——Kafka
    分类预测|基于贝叶斯优化长短期记忆网络的数据分类预测Matlab程序 多特征输入多类别输出 BO-LSTM 附赠预测新数据
    RPA学习天地:企业级RPA设计器核心功能要包括哪些?
    touchGFX综合学习十三、基于cubeMX、正点原子H750开发版、RGB4.3寸屏移植touchGFX完整教程+工程(一)
    使用Robot Framework实现多平台自动化测试
    C&C++内存管理
  • 原文地址:https://blog.csdn.net/Bonbon_wen/article/details/127931803