题目一:
54. 螺旋矩阵https://leetcode.cn/problems/spiral-matrix/
题目要求:
思路:一定要先找好边界。如下图 ,上边界是1234,右边界是8、12,下边界是9、10、11,左边界是5,所以可以确定四个边界所包含的值。然后再循环一层一层往里进入,比如添加完上边界1234后,上边界就需要+1,即下沉到5678行,并与下边界做比较,如果下边界小于上边界,说明所有值都已经添加完毕了。
代码:
class Solution {
public List<Integer> spiralOrder(int[][] matrix) {
List<Integer> list = new ArrayList<>();
// 先拿到行数列数, 然后定义好四个边界
int m = matrix.length;
int n = matrix[0].length;
int up = 0, down = m - 1, left = 0, right = n - 1;
// 每次循环,列表list添加一个外层的数
while (true){
// 添加上边界的值,从左一直到最右边
for (int i = left; i <= right; i++)
list.add(matrix[up][i]);
// 执行完毕后,将上边界下沉; 如果超过了下边界 说明都所有数都添加上了
if (++up > down) break;
// 添加右边界的值,从上到最下
for (int i = up; i <= down; i++)
list.add(matrix[i][right]);
// 执行完毕后,将右边界左移; 如果小于左边界 说明都所有数都添加上了
if (--right < left) break;
// 添加下边界的值, 从右到最左
for (int i = right; i >= left; i--)
list.add(matrix[down][i]);
// 执行完毕后,将下边界上移; 如果小于上边界 说明都所有数都添加上了
if (--down < up) break;
// 添加左边界的值, 从下到最上
for (int i = down; i >= up; i--)
list.add(matrix[i][left]);
// 执行完毕后,将左边界右移; 如果大于右边界 说明都所有数都添加上了
if (++left > right) break;
}
return list;
}
}
注意:①注意for循环中,是要等于到达边界的,比如从左到右添加值时,一定是到达最右边
②添加了哪个边界的值,哪个边界就要向相反方向移动一次,而且必须是++或--先执行才有效
题目二:
234. 回文链表https://leetcode.cn/problems/palindrome-linked-list/题目要求:
思路:直接对链表的值判断是否回文比较繁琐,可以先将链表的值复制到数组中,再使用双指针判断值是否回文。
代码:
class Solution {
public boolean isPalindrome(ListNode head) {
// 将链表的值复制到数组中
List<Integer> vals = new ArrayList<Integer>();
ListNode cur = head;
while (cur != null){
vals.add(cur.val);
cur = cur.next;
}
// 双指针判断是否回文
int l = 0;
int r = vals.size() - 1;
while (l < r){
if (vals.get(l) != vals.get(r))
return false;
l++;
r--;
}
return true;
}
}
题目三:
21. 合并两个有序链表https://leetcode.cn/problems/merge-two-sorted-lists/题目要求:
思路:递归。如果 l1 或者 l2 一开始就是空链表 ,那么没有任何操作需要合并,所以我们只需要返回非空链表。否则,我们要判断 l1 和 l2 哪一个链表的头节点的值更小,然后递归地决定下一个添加到结果里的节点。如果两个链表有一个为空,递归结束。
代码:
class Solution {
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
if (list1 == null)
return list2;
else if (list2 == null)
return list1;
else if (list1.val < list2.val) {
list1.next = mergeTwoLists(list1.next, list2);
return list1;
}
else {
list2.next = mergeTwoLists(list2.next, list1);
return list2;
}
}
}
思路:也可以直接使用暴力解法。
代码:
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode prehead = new ListNode(-1);
ListNode prev = prehead;
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
prev.next = l1;
l1 = l1.next;
} else {
prev.next = l2;
l2 = l2.next;
}
prev = prev.next;
}
// 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
prev.next = l1 == null ? l2 : l1;
return prehead.next;
}
}