数据结构与算法——数组(剑指offer拓展篇)

博主也是第一次当博主,想要做一名名副其实的程序员,当然本质可能还是个商科生,看到博客的朋友可以一起交流经验,wechat:LYI_1998

1.二维数组中的查找

在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

解题思路:

从左下角开始找,左下角的值m依据题目可得,m是行中最小,列中最大,故每次都将m与目标值target比较:
1.当m<target时,由于m为列中最大,故取值右移一位
2.当m>target时,由于m为行中最小,故取值向上移动一位
3.当m=target时,找到该值,返回true
每次比较都可以剔除一行或一列

代码:

package offer;

public class offer_1 {
	public boolean Find(int target, int[][] array) {
//		row:行;cols:列
		int rows = array.length;
		if (rows == 0) {
			return false;
		}
		int cols = array[0].length;
		if (cols == 0) {
			return false;
		}
		int row = rows - 1;
		int col = 0;
		while (row >= 0 && col < cols) {
			if (array[row][col] < target) {
				col++;
			} else if (array[row][col] > target) {
				row--;
			} else {
				return true;
			}
		}
		return false;
	}
}

时间复杂度:O(行+列)
空间复杂度:O(1)

2.数组中重复的数

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

思路:
数组长度为n,则所有数字都在0~n-1中,则其实每个数都有专属自己的位置,如果有多个数在同一位置,即重复项。
例如:从下标i开始,比较下标i上的数字m是否与i相等:
若相等,则i++,接着比较;
若不相等,则数字m与下标m上的数进行比较,再若这两个数字相等,则重复;若不相等,则将数字m与下标m的数字交换位置,使m处于第m位,再重复比较交换过程,直到发现重复的数字。

代码:

package offer;

public class offer_2 {
//	Alt+shift+j实现注释

	/**
	 * @param nums
	 * @param length
	 * @param duplication
	 * @return
	 */
	public static boolean duplicate(int nums[], int length, int[] duplication) {
		if (nums == null || length <= 0) {
			return false;
		}
		for (int a : nums) {
			if (a < 0 || a >= length) {
				return false;
			}
		}

		int temp;
		for (int i = 0; i < length; i++) {
//			下标为i位置上的元素不为i
			while (nums[i] != i) {
//				判断下标为nums[i]位置上的元素值是否为nums[i]
				if (nums[nums[i]] == nums[i]) {
//					若下标为nums[i]上的值等于nums[i],则说明数字重复
					duplication[0] = nums[i];
					return true;
				}
//				将下标为i和下标为nums[i]位置上的元素交换位置
				temp = nums[i];
				nums[i] = nums[temp];
				nums[temp] = temp;

			}
		}
		return false;

	}

//	测试用例
	public static void test_1() {
		System.out.print("test_1:");
		int[] a = { 3, 2, 2, 3, 4, 5 };
		int[] dup = new int[a.length];
		boolean result = duplicate(a, a.length, dup);
		System.out.println(result);
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		test_1();
	}

}

时间复杂度:O(n)
空间复杂度:O(1)

3.题2的变式:不修改数组找出重复的数字

题目:

扫描二维码关注公众号,回复: 9656946 查看本文章

在一个长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但是不能修改输入的数组。例如,如果输入长度为8的数组{2,3,5,4,3,2,6,7},那么对应的输出是重复的数字2或者3

分析:
可以用二分查找法,或者新建辅助数组,再一一对比下标上的数与对应数是否相等,流程和题目二基本相等。

代码:

package offer;

public class offer_2_1 {
	public int getDup(int arr[]) {
		int[] tempArr = new int[arr.length];
		for (int i = 0; i < arr.length; i++) {
			if (arr[i] < 0 || arr[i] >= arr.length) {
				throw new IllegalArgumentException("输入参数不合法");
			} else {
				tempArr[i] = -1;
			}
		}
		for (int i = 0; i < arr.length; i++) {
			if (tempArr[arr[i]] != arr[i]) {
				tempArr[arr[i]] = arr[i];

			} else {
				return arr[i];
			}
		}
		return -1;
	}

	public static void main(String[] args) {
		offer_2_1 findrepeat = new offer_2_1();
		int[] arr = { 3, 4, 5, 3, 2, 3, 5, 6, 5, 4, 5 };
		int value = findrepeat.getDup(arr);
		System.out.println(value);

	}

}

时间复杂度:O(n)
空间复杂度:O(n)

4.构建乘积数组

题目:给定一个数组A[0,1,…,n-1],请构建一个数组B[0,1,…,n-1],其中B中的元素B[i]=A[0]A[1]…*A[i-1]A[i+1]…*A[n-1]。不能使用除法。(注意:规定B[0] = A[1] * A[2] * … * A[n-1],B[n-1] = A[0] * A[1] * … * A[n-2];)
在这里插入图片描述
分析:

时间复杂度为:O(N)
可以把B[i]=A[0]A[1]…A[i-1]A[i+1]…A[n-1]。看成A[0]A[1]…A[i-1]和A[i+1]…A[n-2]A[n-1]两部分的乘积。即通过A[i]项将B[i]分为两部分的乘积。效果相当于是个对角矩阵。

package offer;

import java.util.Arrays;

public class offer_3 {
	public static int[] multiply(int[] A) {
		int length = A.length;
		int[] B = new int[length];
//		边界
		if (A == null || A.length <= 1) {
			return null;
		}
//		计算下三角
//		初始化第一行
		B[0] = 1;
		for(int i =1;i<length;i++) {
			B[i]=B[i-1]*A[i-1];
		}
//		计算上三角
//		初始化最后一行
		int temp = 1;
		for(int i=length-1;i>=0;i--) {
			B[i]=temp*B[i];
			temp=A[i]*temp;
		}
		return B;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] array_1 = {1,2,3,4,5};
		System.out.println(Arrays.toString(multiply(array_1)));
		int[] array_2 = {1,2,5,4,5};
		System.out.println(Arrays.toString(multiply(array_2)));
		int[] array_3 = {1,-2,3,4,-5};
		System.out.println(Arrays.toString(multiply(array_3)));
		
	}

	    

}

发布了8 篇原创文章 · 获赞 4 · 访问量 342

猜你喜欢

转载自blog.csdn.net/NobodyH/article/details/104686900