剑指offer66题思路

3 篇文章 0 订阅
2 篇文章 0 订阅

复习 29顺时针。

调整数组顺序,奇数位于偶数前面,奇数、偶数相对位置不变:

    原书没有说明相对位置不变,可使用两个指针,一个从头检索,一个从尾检索,奇偶相反则呼唤,知道指针重叠。考虑解藕,程序变为1.判断数字奇偶;2.调整位置。

    题目思路:1.使用直接插入,奇数往前移动,偶数位置不动,O(n^2)。

                   2.拷贝数组,第一次遍历数组,奇数放进去,第二次遍历,偶数放进去,O(n),但需要额外空间。

                   3.冒泡,奇偶相邻互换,O(n^2)。

22.输出链表倒数第k个节点

    考虑代码鲁棒性,k大雨节点数,空头节点等问题。

    思路1. 遍历两次数组:第一次得到长度,第二次得到倒数第k个节点。

    思路2.遍历一次数组:两个指针,当遍历到第k个节点时,第二个指针开始遍历,第一个指针到头,第二个便是倒数第k个节点。

24.反转链表

    循环:next指向head的next,head指向pre,(pre指向head,head指向head)作为下一个处理的块。自己指向前节点,并保存后继节点,防止断裂。

    递归:递归找到最后一个节点,返回最后一个节点,当前节点的next的next指向自己,next指向空。后继节点指向自己,自己指空,不存在断裂。

                /*循环*/
		ListNode pre = null;
		ListNode next = null;
		while(head!=null) {
			next = head.next;
			head.next = pre;
			pre = head;
			head = next;
		}
		return pre;
		/*递归*/
		if (head==null||head.next==null) {
			return head;
		}
		ListNode newNode = ReverseList(head.next);
		head.next.next = head;
		head.next = null;
		return newNode;

参考https://www.cnblogs.com/kubixuesheng/p/4394509.html

25.合并链表

    递归:谁小,谁就作为当前节点,指向下一个节点,下一个节点递归求得。

    循环:小的做头节点,比较节点,小的做其后继节点,直到遍历结束,将剩余链表接上,返回头节点。

                if (list1==null) {
			return list2;
		}
		if (list2==null) {
			return list1;
		}
		if (list1.val<=list2.val) {
			list1.next = Merge(list1.next, list2);
			return list1;
		}else {
			list2.next = Merge(list1, list2.next);
			return list2;
		}
                ListNode mergeHead = null;
		ListNode currentNode = null;
		while(list1!=null&&list2!=null) {
			if (list1.val<=list2.val) {
				if (mergeHead==null) {
					mergeHead = currentNode = list1;
				}else {
					currentNode.next = list1;
					currentNode = currentNode.next;
				}
				list1 = list1.next;
			}else {
				if (mergeHead==null) {
					mergeHead = currentNode = list2;
				}else {
					currentNode.next = list2;
					currentNode = currentNode.next;
				}
				list2 = list2.next;
			}
			
		}
		if (list1!=null) {
			currentNode.next = list1;
		}
		if (list2!=null) {
			currentNode.next = list2;
		}
		return mergeHead;

26.二叉树子树结构

    递归:1.判断跟节点和子树跟节点值是否相等,否则遍历左右子树。

            2.相等,再判断子树节点值是否相等。

27.二叉树镜像

    思路1:递归,当前子树非空,交换左右子树。

    思路2:循环,根压入栈,进入循环(栈非空),则出栈,交换左右元素,若左右元素存在,入栈,继续循环,直到栈空。

    

                    if (root==null) {
			return;
		}
		Stack<TreeNode> stack = new Stack<>();
		stack.push(root);
		while(!stack.empty()) {
			TreeNode currentNode = stack.pop();
			TreeNode temp = currentNode.right;
			if (currentNode.left!=null||currentNode.right!=null) {
				currentNode.right = currentNode.left;
				currentNode.left = temp;
			}
			if (currentNode.left!=null) {
				stack.push(currentNode.left);
			}
			if (currentNode.right!=null) {
				stack.push(currentNode.right);
			}
		/*有问题的版本*/	
		/*	if (currentNode.left!=null) {
				currentNode.right = currentNode.left;
				stack.push(currentNode.left);
			}
			if (currentNode.right!=null) {
				currentNode.left = temp;
				stack.push(temp);
			}*/

29.顺时针打印矩阵

    先打上行,再打右列,再打下行,再打左列。

import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printMatrix(int [][] matrix) {
       if (matrix==null||matrix.length == 0||matrix[0] == null||matrix[0].length == 0) {
			return null;
		}
		
		ArrayList<Integer> result = new ArrayList<>();
		
		int topLimit = 0;
		int bottomLimit = matrix.length-1;
		int leftLimit = 0;
		int rightLimit = matrix[0].length-1;
		int init = (int) (bottomLimit>rightLimit?((double)rightLimit/2)+0.5:((double)bottomLimit/2)+0.5);
        int col = 0, row = 0;
		while(col<=init&&row<=init) {
			
			//上行
			for(int i = col; i <= rightLimit; i++) {
				result.add(matrix[topLimit][i]);
				//System.out.print(matrix[topLimit][i]+" ");
			}
			topLimit++;
			
			if (topLimit>bottomLimit) {
				break;
			}
            if (leftLimit>rightLimit) {
				break;
			}
			//右行
			for(int i = topLimit; i <= bottomLimit; i++) {
				result.add(matrix[i][rightLimit]);
				//System.out.print(matrix[i][rightLimit]+" ");
			}
			rightLimit--;
			
            //只有一列时的情况
            
			if (leftLimit>rightLimit) {
				break;
			}
			//下行
			for(int i = rightLimit; i>= leftLimit; i--) {
				result.add(matrix[bottomLimit][i]);
				//System.out.println(matrix[bottomLimit][i]+" ");
			}
			bottomLimit--;
			if (topLimit>bottomLimit) {
				break;
			}
			//左行
			for(int i = bottomLimit; i >= topLimit; i--) {
				result.add(matrix[i][leftLimit]);
				//System.out.println(matrix[i][leftLimit]+" ");
			}
			leftLimit++;
			col++;
			row++;
		}
		
		
		return result;
    }
}


    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值