03.数组中重复的数字
简单的遍历就不说了,主要是优化后的方法,将数组中的数字放到其对应的下标上,容易出错的地方为交换两个数据时,交换完要加一步i—,这样才能避免出现交换后的元素没有进行遍历。
时间复杂度:O(n)
空间复杂度:O(1)
class Solution {
public int findRepeatNumber(int[] nums) {
int n = nums.length;
for(int i = 0; i < n; i++){
int num = nums[i];
if(num == i) continue;
else if(num == nums[num]) {
return num;
}
else{
nums[i] = nums[num];
nums[num] = num;
i--;
}
}
return -1;
}
}
04. 二维数组中的查找
比较简单,可以近似为二叉树的查找,选择左下或者右上的数据作为根进行搜索,注意在Java求二维数组的行列数的时候要判断数组是否为空,否则求列数时会报错
时间复杂度:O(m+n)
空间复杂度:O(1)
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
int n = matrix.length;
if(n == 0) return false;
int m = matrix[0].length;
int i = 0, j = m-1;
while(i < n && j >=0){
if(target == matrix[i][j]){
return true;
}
else if(target > matrix[i][j]){
i++;
}
else {
j--;
}
}
return false;
}
}
06. 从尾到头打印链表
方法较多,除了以下两种方法外还存在许多方法,但其时间复杂度和空间复杂度基本都不能继续优化。
方法一:栈
借用一个辅助栈,满足先进后出的条件,都入栈后再pop,即可得到从尾到头的链表。
时间复杂度:O(n)
空间复杂度:O(n)
class Solution {
public int[] reversePrint(ListNode head) {
Stack<ListNode> s = new Stack<ListNode>();
ListNode temp;
temp = head;
while(temp != null){
s.push(temp);
temp = temp.next;
}
int len = s.size();
int[] ans = new int[len];
for(int i = 0; i < len; i++)
ans[i] = s.pop().val;
}
return ans;
}
}
方法二:链表的原地逆置
这题也可以看作另一题:链表的原地逆置,逆置完后再将链表输出即可,注意链表的原地逆置时pre cur next的操作顺序即可。
时间复杂度:O(n)
空间复杂度:O(n)
class Solution {
public int[] reversePrint(ListNode head) {
ListNode cur = head;
ListNode pre = null;
int len = 0;
while(cur != null){
len++;
ListNode next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
int[] ans = new int[len];
for(int i = 0; i < len; i++){
ans[i] = pre.val;
pre = pre.next;
}
return ans;
}
}