《剑指Offer》笔记题解思路技巧优化_Part_6

news2024/11/13 10:06:11

《剑指Offer》笔记&题解&思路&技巧&优化_Part_6

  • 😍😍😍 相知
  • 🙌🙌🙌 相识
  • 😢😢😢 开始刷题
    • 🟡1.LCR 168. 丑数—— 丑数
    • 🟢2. LCR 169. 招式拆解 II——第一个只出现一次的字符
    • 🔴3. LCR 170. 交易逆序对的总数——数组中的逆序对
    • 🟢4. LCR 171. 训练计划 V——两个链表的第一个公共节点
    • 🟢5. LCR 172. 统计目标成绩的出现次数——在排序数组中查找数字
    • 🟢6. LCR 173. 点名——0~ n-1中缺失的数字
    • 🟢7. LCR 174. 寻找二叉搜索树中的目标节点——二叉搜索树的第k大节点
    • 🟢8. LCR 175. 计算二叉树的深度——二叉树的深度
    • 🟢9. LCR 176. 判断是否为平衡二叉树——平衡二叉树
    • 🟡10. LCR 177. 撞色搭配——数组中数字出现的次数I
    • 🟡11. LCR 178. 训练计划 VI——数组中数字出现的次数II

在这里插入图片描述

😍😍😍 相知

刷题不要一上来就直接干,先看题,明白题说的什么意思,然后想一下用什么现成的算法和数据结构可以快速解决,如果还是无从下手,建议先去看视频,不要直接翻评论或官方代码实现,看完视频,自己在idea中模拟敲几遍代码,如果跑通了,先别急着上leetcode黏贴,而是再回顾一下要点,然后确定自己完全懂了后,在leetcode中手敲,注意是手敲下来!!! 目前我就是采用的这种方法,虽然慢,但是可以维持一周忘不掉它,如果要想长期不忘,只能隔段时间就review一下了,就算是大牛,知道方法,长时间不碰,也不可能保证一次到位把代码敲完一遍过!!!

这是我上一篇博客的,也希望大家多多关注!

  1. 《剑指Offer》笔记&题解&思路&技巧&优化 Java版本——新版leetcode_Part_1
  2. 《剑指Offer》笔记&题解&思路&技巧&优化 Java版本——新版leetcode_Part_2
  3. 《剑指Offer》笔记&题解&思路&技巧&优化 Java版本——新版leetcode_Part_3
  4. 《剑指Offer》笔记&题解&思路&技巧&优化 Java版本——新版leetcode_Part_4
  5. 《剑指Offer》笔记&题解&思路&技巧&优化 Java版本——新版leetcode_Part_5

🙌🙌🙌 相识

根据题型可将其分为这样几种类型:

  1. 结构概念类(数组,链表,栈,堆,队列,树)
  2. 搜索遍历类(深度优先搜索,广度优先搜索,二分遍历)
  3. 双指针定位类(快慢指针,指针碰撞,滑动窗口)
  4. 排序类(快速排序,归并排序)
  5. 数学推理类(动态规划,数学)

😢😢😢 开始刷题

🟡1.LCR 168. 丑数—— 丑数

题目跳转:https://leetcode.cn/problems/chou-shu-lcof/description/

class Solution {
    public int nthUglyNumber(int n) {
        if (n <= 0)
            return -1;
        int[] dp = new int[n];
        dp[0] = 1;
        int id2 = 0, id3 = 0, id5 = 0;
        for (int i = 1; i < n; i++) {
            dp[i] = Math.min(dp[id2] * 2, Math.min(dp[id3] *3, dp[id5] * 5));
            // 这里不用else if的原因是有可能id2(3) * 2 == id3(2) * 3
            // 这种情况两个指针都要后移
            if (dp[id2] * 2 == dp[i])
                id2 += 1;
            if (dp[id3] * 3 == dp[i])
                id3 += 1;
            if (dp[id5] * 5 == dp[i])
                id5 += 1; 
        }
        return dp[n - 1];
    }
}

🟢2. LCR 169. 招式拆解 II——第一个只出现一次的字符

题目跳转:https://leetcode.cn/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/description/

class Solution {
    public char dismantlingAction(String arr) {
        if(arr.length()==0) return ' ';
        if(arr.length()==1) return arr.charAt(0);
        int [] array =new int[26];
        for(int i = 0;i<arr.length();i++){
            array[arr.charAt(i)-'a']++;
        }
        for(int i = 0;i<arr.length();i++){
            if(array[arr.charAt(i)-'a']==1)return arr.charAt(i);
        }
        return ' ';
    }
}

🔴3. LCR 170. 交易逆序对的总数——数组中的逆序对

题目跳转:https://leetcode.cn/problems/shu-zu-zhong-de-ni-xu-dui-lcof/description/

冒泡排序

每检查一次交换一次 就可以产生一次逆序对

归并排序

在这里插入图片描述

class Solution {
	public int reversePairs(int[] nums) {
		if(nums == null || nums.length <= 1){
			return 0;
		}
		return mergeSort(nums, 0, nums.length - 1);
	}
	int mergeSort(int[] nums, int left, int right){
		if(left >= right){
			return 0;
		}
		int mid = (right - left) / 2 + left;
		int x1 = mergeSort(nums, left, mid);
		int x2 = mergeSort(nums, mid + 1, right);
		int x3 = merge(nums, left, mid, mid+1, right);
		return x1 + x2 + x3;
	}
	int merge(int[] nums, int l1, int r1, int l2, int r2){
		int[] temp = new int[r2 - l1 + 1];
		int count = 0;
		int i = l1, j = l2, k = 0;
		while(i <= r1 && j <= r2){
			if(nums[i] > nums[j]){
				count = count + (l2 - i);
				temp[k++] = nums[j++];
			}else{
				temp[k++] = nums[i++];
			}
		}
		while(i <= r1) temp[k++] = nums[i++];
		while(j <= r2) temp[k++] = nums[j++];
		// 把临时数组复制回原数组
		k = 0;
		for(i = l1; i <= r2; i++){
			nums[i] = temp[k++];
		}
		return count;
	}
}

🟢4. LCR 171. 训练计划 V——两个链表的第一个公共节点

题目跳转:https://leetcode.cn/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/description/

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
class Solution {
    ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA==null||headB==null)return null;
        ListNode tempA = headA;
        ListNode tempB = headB;
        boolean a = false;
        boolean b = false;
        while(tempA!=tempB){
            if(tempA.next==null){
                tempA = headB;
                if(a)return null;
                a = true;
            }
            else{
                tempA = tempA.next;
            }
            if(tempB.next==null){
                tempB = headA;
                if(b)return null;
                b = true;
            }
            else{
                tempB = tempB.next;
            }

        }
        return tempA;
    }
}

原来不会死循环

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        
        ListNode h1 = headA, h2 = headB;
        while (h1 != h2) {

            h1 = h1 == null ? headB : h1.next;
            h2 = h2 == null ? headA : h2.next;
        }

        return h1;  
    }

🟢5. LCR 172. 统计目标成绩的出现次数——在排序数组中查找数字

题目跳转:https://leetcode.cn/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/description/

二分查找

class Solution {
    public int countTarget(int[] scores, int target) {
        int left = 0;
        int right = scores.length-1;
        int mid = 0;
        int conut = 0;
        while(left<right){
            mid = (right-left)/2+left;
            if(target <= scores[mid]) right = mid;
            else left = mid+1;
        }
        while(left<scores.length&&scores[left++]==target)conut++;
        return conut;
        
    }
}

🟢6. LCR 173. 点名——0~ n-1中缺失的数字

题目跳转:https://leetcode.cn/problems/que-shi-de-shu-zi-lcof/description/

位运算

class Solution {
    public int takeAttendance(int[] records) {
        if(records[records.length-1]==records.length-1) return records.length;
        int result = 0;
        for(int i = 0;i<records.length;i++){
            result ^=records[i];
            result ^=i;
        }
        result^=records.length;
        return result;
    }
}

二分查找

class Solution {
    public int takeAttendance(int[] records) {
        if(records[records.length-1]==records.length-1) return records.length;
        int left = 0;
        int right =records.length-1;
        while(left<right){
            int mid = (right-left)/2 +left;
            if(records[mid]==mid){
                left = mid+1;
            }
            else{
                right = mid;
            }
        }
        return left;
    }
}

🟢7. LCR 174. 寻找二叉搜索树中的目标节点——二叉搜索树的第k大节点

题目跳转:https://leetcode.cn/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/description/
作为一个普通人,我来分析下这题。

  1. 假设,你花了点时间,练习了二叉树的三种遍历方式: a. 前序遍历 b. 中序遍历 c. 后续遍历
  2. 你也学习了二叉搜索树,深入研究了二叉树搜索树的特性,并且深刻知道二叉搜索树的一个特性:通过中序遍历所得到的序列,就是有序的。

好,有了以上两点知识,我认为你必须能想到(如果想不到,以上两点知识肯定没有学扎实):中序遍历二叉搜索树,遍历的同时,把遍历到的节点存到一个可变数组里(Java的话,可以用ArrayList)。 思路转化为代码,如下:

class Solution {
    public int findTargetNode(TreeNode root, int cnt) {
        if(root==null)return -1;
        if(root.left==null&root.right==null)return root.val;
        ArrayList<Integer> list = new ArrayList<>();
        dfs(root,list);
        return list.get(list.size()-cnt);

    }
    public void dfs(TreeNode root,ArrayList<Integer> list){
        if(root==null)return;
        if(root.left==null&root.right==null){
            list.add(root.val);
            return ;
        }
        if(root.left!=null)dfs(root.left,list);
        list.add(root.val);
        if(root.right!=null)dfs(root.right,list);
    }
}
class Solution {
    public int findTargetNode(TreeNode root, int cnt) {
        if(root==null)return -1;
        if(root.left==null&root.right==null)return root.val;
        ArrayList<Integer> list = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();
        stack.push(root);
        while(!stack.isEmpty()){
            TreeNode temp = stack.peek();
            if(temp==null){
                stack.pop();
                list.add(stack.pop().val);
            }
            else{
                stack.pop();
                if(temp.right!=null) stack.push(temp.right);
                stack.push(temp);
                stack.push(null);
                if(temp.left!=null)stack.push(temp.left);
            }
        }
        return list.get(list.size()-cnt);

    }
}

🟢8. LCR 175. 计算二叉树的深度——二叉树的深度

题目跳转:https://leetcode.cn/problems/er-cha-shu-de-shen-du-lcof/description/

class Solution {
    int max = 0;
    public int calculateDepth(TreeNode root) {
        int deep = 0;
        
        max = dfs(root,deep);
        return max;

    }
    public int dfs(TreeNode root,int num){
        if(root==null)return num;
        if(root.left==null&root.right==null){
            return num+1;
        }
        if(root.left!=null) max = Math.max(max,dfs(root.left,num+1));
        if(root.right!=null) max = Math.max(max,dfs(root.right,num+1));
        return max;
    }
}
class Solution {
    public int calculateDepth(TreeNode root) {
        int max = 0;
        if(root ==null)return 0;
        if(root.left == null&&root.right == null)return 1;
        Queue<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        queue.add(null);
        while(!queue.isEmpty()){
            TreeNode temp = queue.poll();
            if(temp==null){
                max++;
                if(!queue.isEmpty())queue.add(null);
            }
            else{
                
                if(temp.right!=null) queue.add(temp.right);
                if(temp.left!=null)queue.add(temp.left);
            }
        }
        return max;
    }
}

🟢9. LCR 176. 判断是否为平衡二叉树——平衡二叉树

题目跳转:https://leetcode.cn/problems/ping-heng-er-cha-shu-lcof/description/

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    
    public boolean isBalanced(TreeNode root) {
        if(root==null) return true;
        if(root.left==null&&root.right==null)return true;
        if(Math.abs(getHigh(root.left)-getHigh(root.right))<=1){
            return isBalanced(root.left)&&isBalanced(root.right);
        }
        return false;
    }
    public int getHigh(TreeNode root)
    {
        if(root==null) return 0;
        return Math.max(getHigh(root.left),getHigh(root.right))+1;

    }
}

🟡10. LCR 177. 撞色搭配——数组中数字出现的次数I

题目跳转:https://leetcode.cn/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/description/

相同的数异或为0,不同的异或为1。0和任何数异或等于这个数本身。

所以,数组里面所有数异或 = 目标两个数异或 。 由于这两个数不同,所以异或结果必然不为0。

假设数组异或的二进制结果为10010,那么说明这两个数从右向左数第2位是不同的

那么可以根据数组里面所有数的第二位为0或者1将数组划分为2个。

这样做可以将目标数必然分散在不同的数组中,而且相同的数必然落在同一个数组中。

这两个数组里面的数各自进行异或,得到的结果就是答案

在这里插入图片描述

class Solution {
    public int[] sockCollocation(int[] nums) {
        int x = 0; // 用于记录 A B 的异或结果
        
        /** 得到A^B的结果 
            基于异或运算的以下几个性质 
                1. 交换律 
                2. 结合律 
                3. 对于任何数x,都有x^x=0,x^0=x 
        */
        for (int val : nums) x ^= val;

        // x & (-x)本身的作用是得到最低位的1,
        int flag = x & (-x); 
        // 而我们所需要的做到的是:利用这个1来进行分组,也就是做到将A和B区分开
        // 前面已经知道,x是我们需要的结果数A和B相异或的结果,也就是说,x的二进制串上的任何一个1,都能成为区分A和B的条件
        // 因此我们只需要得到x上的任意一个1,就可以做到将A和B区分开来
        

        int res = 0; // 用于记录A或B其中一者

        // 分组操作
        for (int val : nums) {
            // 根据二进制位上的那个“1”进行分组
            // 需要注意的是,分组的结果必然是相同的数在相同的组,且还有一个结果数
            // 因此每组的数再与res=0一路异或下去,最终会得到那个结果数A或B
            // 且由于异或运算具有自反性,因此只需得到其中一个数即可
            if ((flag & val) != 0) {
                res ^= val;
            }
        }
        // 利用先前的x进行异或运算得到另一个,即利用自反性
        return new int[] {res, x ^ res};
            

    }
}

🟡11. LCR 178. 训练计划 VI——数组中数字出现的次数II

题目跳转:https://leetcode.cn/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof/description/

排序

class Solution {
    public int trainingPlan(int[] actions) {
        int n = actions.length;
        Arrays.sort(actions);
        for(int i = 0;i<n-1;i = i+3){
            if(actions[i]!=actions[i+2])
            {
                return actions[i];
            }
        }
        return  actions[n-1];
    }
}

哈希表

class Solution {
    public int singleNumber(int[] actions) {
        HashMap<Integer, Integer> map = new HashMap<>();
        for (int number : actions) map.put(number, map.getOrDefault(number, 0) + 1);
        for (int number : map.keySet()) if (map.get(number) == 1) return number;
        return 0;
    }
}
class Solution {
	public int singleNumber(int[] nums) {
		int[] res = new int[32];
		int m = 1;
		int sum = 0;
		for(int i = 0; i < 32; i++){
			for(int j = 0; j < nums.length; j++){
				if((nums[j] & m) != 0){
				res[i]++;
				}
			}
			res[i] = res[i] % 3;
			sum = sum + res[i] * m;
			m = m << 1;
		}
		return sum;
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1464992.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue样式绑定

1. 绑定 HTML class ①通过class名称的bool值判断样式是否被启用 <template><!--通过样式名称是否显示控制样式--><div :class"{ haveBorder: p.isBorder, haveBackground-color: p.isBackgroundcolor }">此处是样式展示区域</div><br /…

小猫咪不喝水怎么办?主食冻干、主食罐头喂养远离缺水小猫

小猫咪不喝水怎么办&#xff1f;是否可以忽视它不喝水&#xff1f;它们会不会在口渴、缺水的时候自动去找水喝呢&#xff1f;猫的祖先是来自沙漠的猫科动物&#xff0c;在沙漠中生存时几乎找不到水源&#xff0c;因此它们进化出了“低渴感”&#xff0c;同时它们的肾脏也具备了…

EventStream获得数据流,前端配置获得推送的流

如上图所示&#xff0c;请求一个接口&#xff0c;接口以数据流的方式向客户端推送数据&#xff0c;默认需要消息收集一条&#xff0c;在原来的基础上追加&#xff0c;在create-react-app生成的工程中&#xff0c;如果代理使用了中间件http-proxy-middleware&#xff0c;同时dev…

openai sora 只能根据文本生成视频?不,TA 是通用物理世界模拟器

视频生成模型作为世界模拟器 我们探索了在视频数据上进行大规模生成模型的训练。 具体来说&#xff0c;我们联合在可变持续时间、分辨率和长宽比的视频和图像上训练文本条件扩散模型。 我们利用了一个在视频和图像潜在编码的时空补丁上操作的变压器架构。 我们最大的模型So…

Qt_纯虚函数的信号和槽

简介 在C中&#xff0c;纯虚函数是一个在基类中声明但没有实现的虚函数。纯虚函数的声明以 “ 0” 结尾。纯虚函数的目的是为了提供一个接口&#xff0c;但是不提供实现。派生类必须实现纯虚函数&#xff0c;否则它也会成为一个抽象类。纯虚函数可以在基类中定义&#xff0c;也…

PNPM 批量检查和更新项目依赖

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

代码随想录算法训练营第59天 | 583.两个字符串的删除操作 72.编辑距离

两个字符串的删除操作 dp[i][j] 表示使得[0, i-1]的word1子串和[0, j-1]的word2子串相同所需要的最小步数。 递推公式&#xff1a;也是分为word1[i-1]和word2[j-1]相不相等两种情况。如果相等则不需要修改&#xff0c;dp[i][j] dp[i - 1][j - 1]。如果不相等&#xff0c;要么删…

李一舟的AI人工智能课程全部内容

科技一直都在进步&#xff0c;我们唯一能做的就是只能让自己不断地学习&#xff0c;保持终身学习&#xff0c;否则时代抛弃你&#xff0c;连招呼都不会打一个。 分享一下最近很火的某老师的AI人工智能课程及工具&#xff0c;希望对你的人工智能学习有所帮助 课程的内容网盘链接…

酷开科技丨新年新玩法!酷开系统壁纸模式给客厅“换”新

甲辰龙年即将到来&#xff0c;新年新家新气象&#xff0c;快到酷开系统壁纸模式中挑选一款喜欢的壁纸&#xff0c;为新的一年增添一份美好和喜悦吧&#xff01; 酷开科技将更多的电视新玩法带给你&#xff0c;让你的电视成为家庭中的焦点&#xff01;酷开系统壁纸模式&#xf…

在SAP生产系统里面快速地紧急修复BUG修改代码

在SAP生产系统里面快速地紧急修复BUG修改代码

RENISHAW雷尼绍双读数头系统应用分享

在精密回转运动控制中&#xff0c;大多数场合都会对系统的回转定位精度有严格的要求&#xff0c;RENISHAW雷尼绍圆光栅系统&#xff08;RESM增量和RESA绝对值&#xff09;对于回转角度的反馈测量方案能有效的解决运动控制对回转精度的需求。但是配置单个读数头的圆光栅系统的精…

flutter sliver 多种滚动组合开发指南

flutter sliver 多种滚动组合开发指南 视频 https://youtu.be/4mho1kZ_YQU https://www.bilibili.com/video/BV1WW4y1d7ZC/ 前言 有不少同学工作中遇到需要把几个不同滚动行为组件&#xff08;顶部 appBar、内容固定块、tabBar 切换、tabBarView视图、自适应高度、横向滚动&a…

PostgreSQL 实体化视图的使用

上周的教程中&#xff0c;通过 DVD Rental Database 示例&#xff0c;让我们了解了在 PostgreSQL 中创建实体化视图的过程。正如我们所了解的&#xff0c;PostgreSQL 实体化视图提供了一种强大的机制&#xff0c;通过预计算和存储查询结果集为物理表来提高查询性能。接下来的内…

广州市轻工技师学院领导一行莅临泰迪智能科技开展“访企拓岗”活动

2月21日&#xff0c;广州市轻工技师学院技能鉴定处副主任王永润、信息技术产业系副主任邝嘉伟及信息技术产业系骨干教师等一行莅临广东泰迪智能科技股份有限公司产教融合实训基地就深入“访企拓岗”、强化校企合作、促进毕业生充分就业、创新人才培养范式等领域进行了深入交流。…

美团优惠券平台的探索设计与实现

随着电子商务的不断发展&#xff0c;优惠券已经成为吸引用户、促进消费的重要手段之一。美团作为中国领先的生活服务平台&#xff0c;也推出了优惠券平台&#xff0c;为用户提供更多实惠和便捷。本文将探讨美团优惠券平台的设计与实现&#xff0c;以及其在用户消费中的作用和未…

opencv判断二值的情况

目的 先说说理论&#xff1a; 什么叫图像的二值化&#xff1f;二值化就是让图像的像素点矩阵中的每个像素点的灰度值为0&#xff08;黑色&#xff09;或者255&#xff08;白色&#xff09;&#xff0c;也就是让整个图像呈现只有黑和白的效果。在灰度化的图像中灰度值的范围为0…

Flutter插件开发指南01: 通道Channel的编写与实现

Flutter插件开发指南01: 通道Channel的编写与实现 视频 https://www.bilibili.com/video/BV1ih4y1E7E3/ 前言 本文将会通过一个加法计算&#xff0c;来实现 Channel 的双向通讯&#xff0c;让大家有个一个体会。 Flutter插件 Flutter插件是Flutter应用程序与原生平台之间的桥…

Leetcode3036. 匹配模式数组的子数组数目 II

Every day a Leetcode 题目来源&#xff1a;3036. 匹配模式数组的子数组数目 II 解法1&#xff1a;KMP 设数组 nums 的长度为 m&#xff0c;数组 pattern 的长度为 n。 遍历数组 nums 的每个长度是 n1 的子数组并计算子数组的模式&#xff0c;然后与数组 pattern 比较&…

智能图书馆开源项目

结尾有项目链接 技术栈介绍 ☃️前端主要技术栈 技术作用版本Vue提供前端交互2.6.14Vue-Router路由式编程导航3.5.1Element-UI模块组件库&#xff0c;绘制界面2.4.5Axios发送ajax请求给后端请求数据1.2.1core-js兼容性更强&#xff0c;浏览器适配3.8.3swiper轮播图插件&…

1+X电子商务运营数据采集(一)

王某在淘宝网经营着一个水果销售店铺&#xff0c;经过一年多的运营和推广&#xff0c;店铺生意毫无起色&#xff0c;而推广费用却没有少花。为此&#xff0c;王某准备对店铺的客户数据进行分析。采集了网店从开业到目前店铺的已有客户数据与行业客户人群画像进行比对&#xff0…