当前位置: 首页 > news >正文

刷题(删除倒数第N个节点、搜索插入位置、二进制求和、求x平方根、爬楼梯)

1. 删除链表的倒数第N个结点

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
解题思路: 快慢指针

  1. 定义一个新链表,链表在原链表的基础上新增一个头节点 0
  2. 慢指针指向新链表的头节点,后面在改变链表时改变的也是新链表数据
  3. 快指针指向原链表的头节点
    • 快指针首先移动n格,保证与慢指针之间有n个节点作为间隔
    • 慢指针在快指针移动n格之后和快指针同时移动
    • 当快指针移动到最后一个时,慢指针的下一个就是倒数第N个节点
    • 将下一个节点删除并返回新节点的下一个节点,即为删除倒数第N个节点之后的新链表
/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} n
 * @return {ListNode}
 */
var removeNthFromEnd = function(head, n) {
    let dummy=new ListNode(0,head);
    let slow=dummy;
    let fast=head;
    for(let i=0;i<n;i++){
        fast=fast.next; // 循环结束fast与slow指针相差n个结点,之后快慢指针一起移动,当快指针到最后一个 慢指针的下一个就是要删除的结点
    }
    while(fast){
        fast=fast.next;
        slow=slow.next;
    }
    slow.next=slow.next.next;
    return dummy.next;
};
2. 搜索插入位置

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
解题思路:

  1. 如果nums是[1,3,5,7],target是4,结果应该返回2,也就是应该替代大于它的5的位置(把5往后挤)。
  2. 假设target是5,结果同样应该返回2,就是数组中已经存在的5的位置,代替值相等的位置
  3. 假设target是8,则结果应该返回4,数组中没有一个数字比它大,它总是排在最后面,它的index也就是这个数组的length
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var searchInsert=function(nums,target){
    for(let i=0;i<nums.length;i++){
        if(nums[i]>=target){
            return i;
        }
    }
    return nums.length;
}

只要看到题里给出的数组是有序数组,都可以想一想是否可以使用二分法。

3. 加一

给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
解题思路:

  1. 使用数组的join()方法,将数组转换为字符串,将字符串转为数值类型,并且加一,由于精度问题,使用BigInt()转换
  2. 将加一后的数值用toString()转换为字符串
  3. 使用字符串的split()方法,将字符串转换为数组
/**
 * @param {number[]} digits
 * @return {number[]}
 */
var plusOne = function(digits) {
      return (BigInt(digits.join('')) + 1n).toString().split('')
};
4. 二进制求和

给你两个二进制字符串 a 和 b ,以二进制字符串的形式返回它们的和。
**解题思路:**将输入的二进制字符前面加上'0b',并通过BigInt()方法将二进制字符串转换为对应的数字然后相加,将相加后的数字使用toString(2)转换为二进制数字并返回。

a = ‘0b’ + a; 和 b = ‘0b’ + b;:这两行将输入的二进制字符串 a 和 b 前面添加 ‘0b’,以符合 JavaScript 中表示二进制数的惯例。在 JavaScript 中,以 ‘0b’ 开头的字符串被解释为二进制数。

let sum = BigInt(a) + BigInt(b);:使用 BigInt 类型进行二进制数的相加。将带有 ‘0b’ 前缀的二进制字符串转换为对应的 BigInt 数字,然后相加。

return sum.toString(2);:将相加后的 BigInt 数字转换为二进制字符串,使用 toString(2) 方法。这样就得到了两个二进制数相加的结果。

  1. 示例 1:
    • 输入:a = “11”, b = “1”
    • 输出:“100”
  2. 示例 2:
    • 输入:a = “1010”, b = “1011”
    • 输出:“10101”
/**
 * @param {string} a
 * @param {string} b
 * @return {string}
 */
var addBinary = function(a, b) {
    a='0b'+a;
    b='0b'+b;
    let sum=BigInt(a)+BigInt(b);
    return sum.toString(2)
};
5. 求x的平方根(二分法求解

给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。
解题思路:

  • 初始化左指针,右指针,和中间指针。利用二分法时不用非得整一个数组,初始右指针时可以用x/2,算是一个优化,且要向上取整
  • 循环条件为left<=right,计算mid中间值,计算时,用左右两个指针相加除以2即可
  • 最后返回结果时,left会比right大1,所以返回left-1或者返回right都可以
  • 注意当x=0或x=1,可以直接返回x
  1. 示例 1:
    输入:x = 4
    输出:2
  2. 示例 2:
    输入:x = 8
    输出:2
    解释:8 的算术平方根是 2.82842…, 由于返回类型是整数,小数部分将被舍去。
/**
 * @param {number} x
 * @return {number}
 */
var mySqrt = function(x) {
   if(x===0||x===1){
       return x;
   }
   let left=0;
   let right=x-1;
   while(left<=right){
       let mid=Math.floor((left+right)/2);
       let val=mid*mid;
       if(val===x) {
           return mid;
       }
       if(val>x){
           right=mid-1;
       } else {
            // val < x
            left=left=mid+1;
       }
   }
   return right;
};
6. 爬楼梯

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
解题思路: 通过简单的计算,发现这是一个斐波那契数列,可以定义一个数组,并通过f(n)=f(n-1)+f(n-2)给数组元素赋值,返回相应的值。

/**
 * @param {number} n
 * @return {number}
 */
var climbStairs = function(n) {
    /*
        n=1 1                   1
        n=2 11,2                2
        n=3 111,12,21           3
        n=4,22,1111,121,211,112 5
        即f(n)=f(n-1)+f(n-1)
     */
     let res=new Array(n+1).fill(0);
     res[0]=1;
     res[1]=1;
     for(let i=2;i<res.length;i++){
         res[i]=res[i-1]+res[i-2];
     }
     return res[n]
};

优化:由于最终只需要n-1n-2的方法数,因此没有必要将计算的每一个数值都保存,可以从这方面入手,将代码进行优化。

/**
 * @param {number} n
 * @return {number}
 */
var climbStairs = function(n) {
    let pre=1;
    let cur=1;
    for(let i=2;i<n+1;i++){
        let t=cur; // 暂存上一次的cur
        cur=pre+cur; // 当前的cur=上上次cur[pre]+上次cur
        pre=t; // pre更新为上一次的cur 
    }
    return cur;
};

相关文章:

  • 如何在 Windows 11 上查找计算机的 IP 地址?
  • 理解 Rust 中的 String 分配机制
  • 【Vue-组件】学习笔记
  • AI烘焙大赛中的算法:理解PPO、GRPO与DPO的罪简单的方式
  • NVR接入录像回放平台用EasyCVR打造地下车库安防:大型商居安全优选方案
  • Windows 图形显示驱动开发-WDDM 2.0功能_重排范围
  • 阿里云大模型训练与推理开发
  • 关于点卷积
  • 利用Ollama对AI大模型进行攻击
  • vue3 处理文字 根据文字单独添加class
  • MySQL基础 [五] - 表的增删查改
  • 进程状态(运行 阻塞 僵尸)及其场景分析
  • 智谛达多功能人形机器人:未来生活的得力助手
  • DMA 概念与讲解
  • LeetCode 热题 100_完全平方数(84_279_中等_C++)(动态规划(完全背包))
  • 随机产生4位随机码(java)
  • 设计模式之享元模式
  • 图解AUTOSAR_SWS_FlexRayDriver
  • 使用分布式锁和乐观锁解决超卖问题
  • 闪蒸高密度聚乙烯无纺布市场报告:探索高性能材料的新机遇
  • 装修网站建设方案书/长春免费网上推广
  • dw如何做商业网站/淘宝seo培训
  • 上海营销网站设计/今日疫情实时数据
  • 站点-将网站添加到区域变灰色无法添加如何解决/2024年度关键词
  • 外贸都用什么网站/广告公司取名字参考大全
  • 如何查询网站打开速度变慢/搜索引擎广告形式有