动态数组练习题(二)

118. 杨辉三角

给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。
在杨辉三角中,每个数是它左上方和右上方的数的和。

示例:

输入: 5
输出:
[
[1],
[1,1],
[1,2,1],
[1,3,3,1],
[1,4,6,4,1]
]

解题思路:杨辉三角,每一行第一个元素和最后一个元素都是1,中间的元素都是上面元素之和。第一、二行可以不用考虑,都是1,第i行的中间元素都是i-1行两个元素之和。

public List<List<Integer>> generate(int numRows) {
        List<List<Integer>> lists = new ArrayList<List<Integer>>();
        //外层循环表示lists 行数
        for (int i = 1; i <= numRows; i++) {
        	ArrayList<Integer> list = new ArrayList<Integer>();
        	//内层循环表示list 的角标
			for(int j=0;j<i;j++){
				//每一行第一个元素和最后一个元素都是1
				if(j==0 || j==i-1){
					list.add(1);
				}else{
					//ArrayList的角标从零开始
					list.add(lists.get(i-2).get(j)+lists.get(i-2).get(j-1));
				}
			}
        	lists.add(list);
		}
        return lists;
    }
766. 托普利茨矩阵

如果一个矩阵的每一方向由左上到右下的对角线上具有相同元素,那么这个矩阵是托普利茨矩阵。
给定一个 M x N 的矩阵,当且仅当它是托普利茨矩阵时返回 True。

示例 1:

输入:
matrix = [
[1,2,3,4],
[5,1,2,3],
[9,5,1,2]
]
输出: True
解释:
在上述矩阵中, 其对角线为:
“[9]”, “[5, 5]”, “[1, 1, 1]”, “[2, 2, 2]”, “[3, 3]”, “[4]”。
各条对角线上的所有元素均相同, 因此答案是True。

示例 2:

输入:
matrix = [
[1,2],
[2,2]
]
输出: False
解释:
对角线"[1, 2]"上的元素不同。

解题思路:如果满足左上到右下的对角线具有相同元素,说明这个矩阵是托普利茨矩阵。我们可以看示例一的矩阵,对角线的元素下标都是逐步加一,我们可以从第一行的每个元素根据对角线遍历,但第一行的最后一个元素没有对角线,所以不用管,同理第一列的最后一个元素也不用管,剩下的对角线我们可以从第一列的每个元素进行遍历。

public boolean isToeplitzMatrix(int[][] matrix) {
		int row=matrix.length;//行
		int col=matrix[0].length;//列
		
		//1.列方向几个头
		//i表示列
		for (int i = 0; i < col-1; i++) {
			int x=1;
			int y=i+1;
			while(x>=0&&x<row&&y>=0&&y<col){
				//如果不相等直接结束
				if(matrix[x][y]!=matrix[0][i]){
					return false;
				}
				x++;
				y++;
			}
		}
		
		//2.行方相几个头
		//i表示行
		for (int i = 1; i < row-1; i++) {
			int x=i+1;
			int y=1;
			while(x>=0&&x<row&&y>=0&&y<col){
				if(matrix[x][y]!=matrix[i][0]){
					return false;
				}
				x++;
				y++;
			}
		}
		return true;
	}
1013. 将数组分成和相等的三个部分

给定一个整数数组 A,只有我们可以将其划分为三个和相等的非空部分时才返回 true,否则返回 false。

形式上,如果我们可以找出索引 i+1 < j 且满足 (A[0] + A[1] + … + A[i] == A[i+1] + A[i+2] + … + A[j-1] == A[j] + A[j-1] + … + A[A.length - 1]) 就可以将数组三等分。

示例 1:
输出:[0,2,1,-6,6,-7,9,1,2,0,1]
输出:true
解释:0 + 2 + 1 = -6 + 6 - 7 + 9 + 1 = 2 + 0 + 1
示例 2:
输入:[0,2,1,-6,6,7,9,-1,2,0,1]
输出:false
示例 3:
输入:[3,3,6,5,-2,2,5,1,-9,4]
输出:true
解释:3 + 3 = 6 = 5 - 2 + 2 + 5 + 1 - 9 + 4

解析:先计算出数组的总和,再让sum/3这是每个部分的和用key存储,遍历整个数组,用key减去每个元素,直到key为0,就分为一组。

public boolean canThreePartsEqualSum(int[] A) {
        //1.先算和sum  
		int sum=0;
		for(int num:A){
			sum+=num;
		}
		int key=sum/3;  //sum/3是每个部分的和
		int temp=0;  //记录组数
		for(int i=0;i<A.length;i++){
			key-=A[i];
			if(key==0){//当key等于0时,分成一组
				temp++;
				key=sum/3;
			}
		}
		return temp==3;
    }
167. 两数之和 II - 输入有序数组

给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。

函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。

说明:

返回的下标值(index1 和 index2)不是从零开始的。
你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。

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

**解析:**利用二分查找解决。遍历数组去找与target-numbers[i]相同的数,并返回相应的角标。

	public int[] twoSum(int[] numbers, int target){
		for(int i=0;i<numbers.length;i++){
			int index = binarySearch(numbers,i+1,numbers.length-1,target-numbers[i]);
			if(index!=-1){
				return new int[]{i+1,index+1};
			}
		}
		return null;
	}
	
	//二分查找,时间复杂度O(nlogn)
	//begin:开始的角标
	//end:结束的角标
	//key:target-numbers[i]
	public int binarySearch(int[] arr,int begin,int end,int key){
		int min=begin;
		int max=end;
		int mid=(min+max)/2;
		while(arr[mid]!=key){
			if(arr[mid]>key){
				max=mid-1;
			}else if(arr[mid]<key){
				min=mid+1;
			}
			if(min>max){
				return -1;
			}
			mid=(min+max)/2;
		}
		return mid;
	}
498. 对角线遍历

给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素,对角线遍历如下图所示。

示例:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,4,7,5,3,6,8,9]

解析:

public int[] findDiagonalOrder(int[][] matrix) {
		/**1.横纵坐标是偶数 右上    奇数  左下
		 * 2.右上:行末  列没有   i==0 j!=col-1 列+1
		 * 	列末    j=col-1  行+1
		 * 	其它情况 行-1 列+1
		 * 左下:j==0 i!=row-1 行+1
		 * 		i==row-1 列+1
		 * 		其它情况:行+1 列-1  
		 */
		if(matrix==null||matrix.length==0||matrix[0].length==0){
			return new int[]{};
		}
		
		int row=matrix.length;
		int col=matrix[0].length;
		//二维数组只有一行
		if(row==1){
			return matrix[0];
		}
		//二位数组只有一列
		int[] nums=new int[row*col];
		if(col==1){
			for(int i=0;i<row;i++){
				nums[i]=matrix[i][0];
			}
			return nums;
		}
		int i=0;
		int j=0;
		int index=0;
		while(i<row&&j<col){
			//读取(i,j)的元素
			nums[index++]=matrix[i][j];
			if((i+j)%2==0){//右上
				if(i==0&&j!=col-1){
					j++;
				}else if(j==col-1){
					i++;
				}else{
					i--;
					j++;
				}
			}else{//左下
				if(j==0&&i!=row-1){
					i++;
				}else if(i==row-1){
					j++;
				}else{
					i++;
					j--;
				}
			}
		}
		return nums;
    }
724. 寻找数组的中心索引

给定一个整数类型的数组 nums,请编写一个能够返回数组“中心索引”的方法。

我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相加的和。

如果数组不存在中心索引,那么我们应该返回 -1。如果数组有多个中心索引,那么我们应该返回最靠近左边的那一个。

示例 1:
输入:
nums = [1, 7, 3, 6, 5, 6]
输出: 3
解释:
索引3 (nums[3] = 6) 的左侧数之和(1 + 7 + 3 = 11),与右侧数之和(5 + 6 = 11)相等。
同时, 3 也是第一个符合要求的中心索引。
示例 2:
输入:
nums = [1, 2, 3]
输出: -1
解释:
数组中不存在满足此条件的中心索引。

解析:

/**
	 * 1.求总和sum
	 * 2.左边的和leftSum 随着i的移动进行累加
	 * 3.右边的和rightSum sum-leftSum-nums[i]
	 * 
	 * */
	public int pivotIndex(int[] nums) {
		if(nums==null){
			return -1;
		}
		int sum=0;
		int leftSum=0;
		int rightSum=0;
		for(int num:nums){
			sum+=num;
		}
		for(int i=0;i<nums.length;i++){
			if(i==0){
				leftSum=0;
			}else{
				leftSum+=nums[i-1];
			}
			rightSum=sum-leftSum-nums[i];
			if(leftSum==rightSum){
				return i;
			}
		}
		return -1;
	}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值