剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
本题的核心就是对nums[i]%2是为0还是为1,可以两次循环,一次输出奇数,第二次输出偶数。
class Solution {
public int[] exchange(int[] nums) {
int n = nums.length;
int index = 0;
int[] ans = new int[n];
for(int i:nums){
if((i%2)==1){
ans[index++]=i;
}
}
for(int i:nums){
if((i%2)==0){
ans[index++]=i;
}
}
return ans;
}
}
并且不在乎排序,只需要奇数在偶数前即可,所以可以直接遍历并且判断。
class Solution {
public int[] exchange(int[] nums) {
int n = nums.length;
int left=0;
int right =n-1;
int[] ans = new int[n];
for(int num:nums){
if((num%2)==1){
ans[left++]=num;
}
if((num%2)==0){
ans[right--]=num;
}
}
return ans;
}
}
剑指 Offer 22. 链表中倒数第k个节点
删除倒数第k个节点,首先便是遍历得到head长度,然后k和head长度的差,就是head=head.next的次数,剩下的就是结果。
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode cur = head;
int t = 0;
while(cur!=null)
{
cur=cur.next;
t++;
}
for (cur = head; k<t; k++) {
cur = cur.next;
}
return cur;
}
}
第二种就是双指针方法,用快慢指针就可以找到对应节点
class Solution {
public ListNode getKthFromEnd(ListNode head, int k) {
ListNode former = head, latter = head;
for(int i = 0; i < k; i++)
former = former.next;
while(former != null) {
former = former.next;
latter = latter.next;
}
return latter;
}
}
剑指 Offer 25. 合并两个排序的链表
类似数组的合并。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dum = new ListNode(0), cur = dum;
while(l1 != null && l2 != null) {
if(l1.val < l2.val) {
cur.next = l1;
l1 = l1.next;
}
else {
cur.next = l2;
l2 = l2.next;
}
cur = cur.next;
}
cur.next = l1 != null ? l1 : l2;
return dum.next;
}
}
但是第二种递归法确实是没有想到的,而且还是理解的不是很透彻,对不光是对这一题,也是对递归并不是太透彻。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
} else if (l2 == null) {
return l1;
} else if (l1.val < l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
73. 矩阵置零
可以定义两个布尔型数组或者哈希表来存储为0的行和列,然后在循环遍历,更改相对应的行和列为0.
class Solution {
public void setZeroes(int[][] matrix) {
int m=matrix.length,n=matrix[0].length;
HashSet<Integer> row = new HashSet<>();
HashSet<Integer> col = new HashSet<>();
for(int i = 0;i<m;i++){
for(int j=0;j<n;j++){
if(matrix[i][j]==0){
row.add(i);
col.add(j);
}
}
}
for(int r:row){
for(int j=0;j<n;j++){
matrix[r][j]=0;
}
}
for(int c:col){
for(int i=0;i<m;i++){
matrix[i][c]=0;
}
}
}
}
//or
class Solution {
public void setZeroes(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
boolean[] row = new boolean[m];
boolean[] col = new boolean[n];
for(int i = 0;i<m;i++){
for(int j = 0;j<n;j++){
if(matrix[i][j] == 0){
row[i] = col[j] = true;
}
}
}
for(int i=0;i<m;i++){
for(int j = 0;j<n;j++){
if(row[i]||col[j]){
matrix[i][j]=0;
}
}
}
}
}
还学到了自我感觉有点复杂的,但是去一步步分析,确实更加简单,也不需要额外空间去存放,甚至感觉二刷也不一定会写出来。
class Solution {
public void setZeroes(int[][] matrix) {
int m = matrix.length, n = matrix[0].length;
boolean flagCol0 = false, flagRow0 = false;
for (int i = 0; i < m; i++) {
if (matrix[i][0] == 0) {
flagrow0 = true;
}//如果每一行的第一位有0,则标记为true
}
for (int j = 0; j < n; j++) {
if (matrix[0][j] == 0) {
flagcol0 = true;
}//如果每一列的第一位有0,则标记为true
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (matrix[i][j] == 0) {
matrix[i][0] = matrix[0][j] = 0;
}//把置零信息同时存到起对应行列的最左面和最上面
}
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
if (matrix[i][0] == 0 || matrix[0][j] == 0) {
matrix[i][j] = 0;
}//把上面的置零位置的每一行每一列也置零
}
}
if (flagrow0) {
for (int i = 0; i < m; i++) {
matrix[i][0] = 0;
}//对标记为True的首行全部置零
}
if (flagcol0) {
for (int j = 0; j < n; j++) {
matrix[0][j] = 0;
}//对标记为True的首列全部置零
}
}
}