leetcode算法入门day3——双指针

第一题 两数之和1

@Date 2022年1月16日
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,
并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。

package day3双指针;

public class 两数之和1 {
	public int[] twoSum(int[] nums, int target) {
		int [] two = new int[2];
		for (int i = 0; i < nums.length; i++) {
			for (int j = i+1; j < nums.length; j++) {
				if (nums[i] + nums[j] == target) {
					two[0] = i;
					two[1] = j;
					return two;
					//return new int[]{i, j};
				}
			}
		}
		return two;
		
		/*
		 * 方法二:hash表
	 	Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>();
        for (int i = 0; i < nums.length; ++i) {
            if (hashtable.containsKey(target - nums[i])) {
                return new int[]{hashtable.get(target - nums[i]), i};
            }
            hashtable.put(nums[i], i);//否则就加入到hash表中
        }
        return new int[0];
		 */
    }
}

第二题 两数之和167

@Date 2022年1月16日
给定一个已按照 非递减顺序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。
函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。
numbers 的下标 从 1 开始计数 ,
所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。
你可以假设每个输入 只对应唯一的答案 ,
而且你 不可以 重复使用相同的元素。
示例 1:
输入:numbers = [2,7,11,15], target = 9
输出:[1,2]
解释:2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。

package day3双指针;

public class 两数之和167 {
	public int[] twoSum(int[] numbers, int target) {
		
		//方法一:暴力搜索
		int [] two = new int[2];
		for (int i = 0; i < numbers.length; i++) {
			for (int j = i+1; j < numbers.length; j++) {
				if (numbers[i] + numbers[j] == target) {
					two[0] = i+1;
					two[1] = j+1;
					return two;
					//return new int[]{i, j};
				}
			}
		}
		return two;
		
		/*
		方法二:
		在数组中找到两个数,使得它们的和等于目标值,可以首先固定第一个数,然后寻找第二个数,
		第二个数等于目标值减去第一个数的差。利用数组的有序性质,可以通过二分查找的方法寻找第二个数。
		为了避免重复寻找,在寻找第二个数时,只在第一个数的右侧寻找。
		 */
		
		/*
		初始时两个指针分别指向第一个元素位置和最后一个元素的位置。每次计算两个指针指向的两个元素之和,并和目标值比较。
		如果两个元素之和等于目标值,则发现了唯一解。如果两个元素之和小于目标值,则将左侧指针右移一位。
		如果两个元素之和大于目标值,则将右侧指针左移一位。移动指针之后,重复上述操作,直到找到答案。
		int low = 0, high = numbers.length - 1;
        while (low < high) {
            int sum = numbers[low] + numbers[high];
            if (sum == target) {
                return new int[]{low + 1, high + 1};
            } else if (sum < target) {
                ++low;
            } else {
                --high;
            }
        }
        return new int[]{-1, -1};
        
        1.public int[] twoSum(int[] nums, int target),方法定义了返回int[](也就是int数组类型)
		2.return new int[0];中new int[0]代表着创建了一个长度为0的int数组,
		这里与int[] arr = new int[0]进行对比可能更容易理解,后者是创建了数组并将其引用赋值给变量arr,
		return new int[0];而这里并没有赋值操作,而是直接返回了这个数组
		3.这段代码中如果
		if(target == (nums[i] + nums[j])){
		return new int[]{i,j};
		}
	这段代码判断为true则进入if语句的执行代码,return new int[]{i,j};,也就是找到了目标值,
	结束方法返回目标值为数组的类型,若是if语句判断为false则不进入,直到所有循环结束都没有找到就会顺序执行,
	执行return new int[0],返回一个长度为0的数组,长度为0的数组也是个数组,存在引用
        
		 */
    }
}

第三题 移除元素27

**@Date 2022年1月16日
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。**

package day3双指针;

public class 移除元素27 {
	public int removeElement(int[] nums, int val) {
		//快慢指针
		int j = 0;
		for (int i = 0; i < nums.length; i++) {
			if (nums[i]!=val) {
				nums[j]=nums[i];
				j++;
			}
		}
		return j;

    }
}

第四题 移动零283

**@Date 2022年1月16日
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。**

package day3双指针;

public class 移动零283 {
	public void moveZeroes(int[] nums) {
		//方法一:快慢指针
//		我们创建两个指针i和j,第一次遍历的时候指针j用来记录当前有多少非0元素。即遍历的时候每遇到一个非0元素就将其往数组左边挪,第一次遍历完后,j指针的下标就指向了最后一个非0元素下标。
//		第二次遍历的时候,起始位置就从j开始到结束,将剩下的这段区域内的元素全部置为0。
		int j = 0;
		for (int i = 0 ; i < nums.length; i++) {
//			if (nums[i]==0) {
//				for (int j = i+1; j < nums.length; j++) {
//					nums[i] = nums[j];
//				}
//				nums[nums.length-1] = 0;
//			}else {
//				break;
//			}
			if (nums[i]!=0) {
				nums[j] = nums[i];
				j++;
			}
		}
		for (int i = j; i < nums.length; i++) {
			nums[i] = 0;
		}
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值