第54题 螺旋矩阵
题目描述:给定一个包含 m x n 个元素的矩阵(m 行, n 列),请按照顺时针螺旋顺序,返回矩阵中的所有元素。
示例 1:
输入:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
输出: [1,2,3,6,9,8,7,4,5]
示例 2:
输入:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
输出: [1,2,3,4,8,12,11,10,9,5,6,7]
这道题我自己没有做出来所以参考了题解
public static List<Integer> spiralOrder(int[][] matrix) {
List ans = new ArrayList();
if (matrix.length == 0) return ans;
int R = matrix.length, C = matrix[0].length;
boolean[][] seen = new boolean[R][C];
int[] dr = {0, 1, 0, -1};
int[] dc = {1, 0, -1, 0};
int r = 0, c = 0, di = 0;
for (int i = 0; i < R * C; i++) {
ans.add(matrix[r][c]);
seen[r][c] = true;
int cr = r + dr[di];
int cc = c + dc[di];
if (0 <= cr && cr < R && 0 <= cc && cc < C && !seen[cr][cc]) {
r = cr;
c = cc;
} else {
di = (di + 1) % 4;
r += dr[di];
c += dc[di];
}
}
return ans;
}
这道题的解法比较直接。通过设置一个行号列号来指示当前的行和列。并且给当前位置是否访问做了标记。我们先按照行不变列变大得方式来寻找下一个。如果已经访问了,或者是超出界限了就顺时针旋转。所以增长的方式一共有4中。就把这个四种情况都放入到了两个数组里面方便访问。很明显时间复杂度和空间复杂度都为O(N)
第55题 跳跃游戏(简单)
题目描述:给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个位置。
示例1:
输入: [2,3,1,1,4]
输出: true
解释: 从位置 0 到 1 跳 1 步, 然后跳 3 步到达最后一个位置。
示例2:
输入: [3,2,1,0,4]
输出: false
解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。
java代码:
public static boolean canJump(int[] nums) {
int max=0;
int i = 0;
while(i<=max){
max = max>i+nums[i]?max:i+nums[i];
if(max==nums.length-1) return true;
i++;
}
if(max!=nums.length-1) return false;
return true;
}
这道题比较简单。方法就是设置一个最大访问的下标。因为我们每次访问一个数字之后就可以更新一下这个下标。若是最大下标指向了最后一个,那么返回ture,若访问过程中,用于遍历的i超过了最大下标,那么久返回false。
第56题合并区间
题目描述:给出一个区间的集合,请合并所有重叠的区间。
示例 1:
输入: [[1,3],[2,6],[8,10],[15,18]]
输出: [[1,6],[8,10],[15,18]]
解释: 区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:
输入: [[1,4],[4,5]]
输出: [[1,5]]
解释: 区间 [1,4] 和 [4,5] 可被视为重叠区间。
我的java代码:
public class Merge_Intervals56 {
public int[][] merge(int[][] intervals) {
if(intervals.length<=1) return intervals;
sort(intervals);
Stack<int[]> stack = new Stack<>();
int max = 0;
int min = 0;
for(int i = 0;i<intervals.length;i++){
if(intervals[i][0]<=max&&!stack.isEmpty()){//合并
int[] temp = stack.pop();
temp[0] = temp[0]>intervals[i][0]?intervals[i][0]:temp[0];
temp[1] = temp[1]<intervals[i][1]?intervals[i][1]:temp[1];
stack.push(temp);
max = temp[1];
}else
{
stack.push(intervals[i]);
max = intervals[i][1];
}
}
int size = stack.size();
int[][] result = new int[size][2];
size = size-1;
while(!stack.isEmpty()&&size>=0){
result[size] = stack.pop();
size--;
}
return result;
}
public void sort(int[][] m){
for(int i =0;i<m.length-1;i++){
for(int j = i+1;j<m.length;j++){
if(m[i][0]>m[j][0]){
int[] tem = m[i];
m[i] = m[j];
m[j] = tem;
}
}
}
}
}
我是先将其排序之后,利用一个栈俩实现了合并。思路比较简单。
但是时间消耗比较厉害。下面是一个人的答案。思路差不多,不过代码比较简洁。从中可以了解多维数组的排序:
排序的方式
// 根据二维数组第一个数字大小按每一行整体排序
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] o1, int[] o2) {
// TODO Auto-generated method stub
return o1[0] - o2[0];
}
});
}
这种排序的方式要总结下来。
第58题 最后一个单词的长度
太简单了不写了