《剑指offer》思路与实现总结--Java

二叉树

  • 二叉树的深度(最长的加1
    在这里插入图片描述
  • 平衡二叉树
if (root == null)  
            return 0;  
        int left = lengthOfTree(root.left);  
        int right = lengthOfTree(root.right);  
		if (Math.abs(left - right) > 1) 

数组

  • 判断奇偶
if ((array[j] & 1) == 0 && (array[j + 1] & 1) == 1) 
//与1位与得1就是奇数,1只有最后一位是1
  • 数字在排序数组中出现的次数
//找出第一个k的位置
	//找出第一个位置k的终止条件:要么middleIndex=0;要么middleIndex > 0但是middleIndex-1处的位置不等于k
			if((middleIndex > 0 && nums[middleIndex-1]!=k) || middleIndex == 0){
				return middleIndex;
			}else{
				end = middleIndex -1;
	//找出最后一个k的位置 反之           number = lastK - firstK + 1;

栈 队列 堆

  • 两个栈实现队列
Stack<Integer> in = new Stack<Integer>();
Stack<Integer> out = new Stack<Integer>();

public void push(int node) {
    in.push(node);
}

public int pop() throws Exception {
    if (out.isEmpty())
        while (!in.isEmpty())
            out.push(in.pop());

    if (out.isEmpty())
        throw new Exception("queue is empty");

    return out.pop();
}
  • Java 的 PriorityQueue 实现了堆的能力,PriorityQueue 默认是小顶堆,可以在在初始化时使用 Lambda 表达式 (o1, o2) -> o2 - o1 来实现大顶堆。
//大小为 K 的最小堆
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((o1, o2) -> o2 - o1);
    for (int num : nums) {
        maxHeap.add(num);
        if (maxHeap.size() > k)
            maxHeap.poll();
            //pop()函数和poll()函数都是从首位置取元素并删除; 区别在于,pop遇到null会报异常。poll遇到null会返回null
            //stack.peek(); 返回栈顶元素,但不在堆栈中删除它。
    }

链表

  • 删除重复结点
public ListNode deleteDuplication(ListNode pHead) {
    if (pHead == null || pHead.next == null)
        return pHead;
    ListNode next = pHead.next;
    if (pHead.val == next.val) {
        while (next != null && pHead.val == next.val)
            next = next.next;
        return deleteDuplication(next);
    } else {
        pHead.next = deleteDuplication(pHead.next);
        return pHead;
    }
}
  • 链表中倒数第 K 个结点
 ListNode P1 = head;
    while (P1 != null && k-- > 0)
        P1 = P1.next;
    if (k > 0)
        return null;
    ListNode P2 = head;
    while (P1 != null) {
        P1 = P1.next;
        P2 = P2.next;
    }
    return P2;
  • 反转链表
//递归三步:basecase+拆解+组合
//basecase
if(head == null || head.next ==null) return head;
new newNode = ReverseList(head.next);
//原node1->next = node2  将node2->next指向node1  node1->next->next = node1
head.next.next = head;
head.next=null;
return newNode;

迭代(头插)

ListNode pre =null;
ListNode cur =head;
while(cur!=null){
ListNode nex = cur.next;
cur.next = pre;//反转指针
//三人行
pre = cur;
cur = nex;
}
return per;
  • 合并两个排序的链表
if (list1.val <= list2.val) {
        list1.next = Merge(list1.next, list2);
        return list1;
    } else {
        list2.next = Merge(list1, list2.next);
        return list2;
    }
  • 两个链表的第一个公共节点
    设 A 的长度为 a + c,B 的长度为 b + c,其中 c 为尾部公共部分长度,可知 a + c + b = b + c + a。
ListNode l1=pHead1, l2=pHead2;
while(l1 !=l2){
l1 =(l1 == null) ? pHead2 : l1.next;
l2 =(l2 == null) ? pHead1 : l2.next;
}
return l1;

贪心

  • 剪绳子 剪成 2和3 乘积最大
if(n-long3/3 ==1)
long3 --;
int long2 = (n-long3^3)/2
return Math.pow(3,long3)*Math.pow(2,long2);

动态规划

  • 股票的最大利润
int max = 0;
int head =  arr[0];
for(int i;i<arr.lenth;i++){
//寻找最小的
head = Math.min(head,arr[i]);
//寻找最大的数
max = Math.max(max,arr[i]-head);
}

二分查找

  • 旋转数组的最小数字
//将旋转数组对半分可以得到一个包含最小元素的新旋转数组,以及一个非递减排序的数组
//非递减数组的第一个元素一定小于等于最后一个元素
while(l<h){
m = l+(h-1)/2;
if(arr[m]<=arr[h])
h=m;
else {
l=m+1;
	}
}
return arr[l];
  • 数字在排序数组中出现的次数

github必看:剑指Offer题解

在这里插入图片描述

剑指offer-Java实现完整代码

剑指offer思路总结-原书顺序

在这里插入图片描述


黄小邪自刷总结

剑指offer所有的题目总结

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值