【读书笔记:算法小抄】左、右指针的常用算法(二分搜索、两数之和、反转数组)——Java实现

本节内容

  1. 二分搜索;
  2. 两数之和:输入一个已按照升序排列的有序数组nums和一个目标值target,在nums中找到两个数使得它们相加之和等于target,请返回这两个数的索引;
  3. 反转数组。

代码与解读

package com.company;
import static java.lang.System.out;
import java.util.*;

public class Main {
    /* 二、左、右指针的常用算法 */
    // 1. 二分搜索--双指针算法(非递归算法)
    public static int binarySearch(int[] nums, int target){
        int left = 0;
        int right = nums.length - 1;

        while (left <= right){
            int mid = (left + right) / 2;
            if (nums[mid] == target)
                return mid;
            else if (target < nums[mid])  // 小于中间值,在左半边搜索
                right = mid - 1;
            else  // 大于中间值,在右半边搜索
                left = mid + 1;
        }

        return -1;
    }

    // 2. 两数之和:输入一个已按照升序排列的有序数组nums和一个目标值target,
    // 在nums中找到两个数使得它们相加之和等于target,请返回这两个数的索引。
    // 备注:可以假设这两个数一定存在,索引从1开始算,两个数的索引不可相同。
    // 提示:只要数组有序,就应该想到双指针技巧,此题解法类似二分搜索。
    public static int[] twoSum(int[] nums, int target){
        int left = 0;
        int right = nums.length - 1;

        // 由于数组是有序的,所以可以控制两端的左右指针来控制“和值”
        while (left < right){
            int sum = nums[left] + nums[right];
            if (sum == target)
                return new int[]{left + 1, right + 1};
            else if (sum < target)
                left++;  // sum小了就左移一个,让sum大一点
            else
                right--;  // sum比target大了,就右移一个,让sum小一点
        }

        return new int[]{-1, -1};
    }

    // 3. 反转数组
    public static void reverse(int[] nums){
        int left = 0;
        int right = nums.length - 1;

        while (left < right){
            // 交换左右指针所指之数
            int temp = nums[left];
            nums[left] = nums[right];
            nums[right] = temp;

            left++; right--;
        }
    }

    public static void main(String[] args) {
        // 定义一个1-5的有序数组来测试上面的函数
        int[] nums = {1, 2, 3, 4, 5};
        int target = 3;

        // 1) 二分搜索
        int res1 = binarySearch(nums, target);
        out.println(res1); // 2

        // 2) 两数之和
        int[] res2 = twoSum(nums, target);
        out.println(res2[0] + ", " + res2[1]); // 1, 2

        // 3) 反转数组
        reverse(nums);
        for (int i : nums) {
            out.println(i + " "); // 5 4 3 2 1
        }
        
    }

}


如果你认为对你有用,关注我的微信公众号支持我一下吧!~

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值