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;
}