万物的算法日记|第三天

这篇具有很好参考价值的文章主要介绍了万物的算法日记|第三天。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

笔者自述:

一直有一个声音也一直能听到身边的大佬经常说,要把算法学习搞好,一定要重视平时的算法学习,虽然每天也在学算法,但是感觉自己一直在假装努力表面功夫骗了自己,没有规划好自己的算法学习和总结,因为后半年也该找实习了,所以每日的算法题要进行恶补,勤能补拙,因此有了这一个算法日记系列;

必读: 大佬你好,感谢您的阅读,这篇文章是我的算法笔记,方便我每日回顾;
为了不耽误您的时间,我把本篇日记的考点方向和算法知识总结列出来,如果对您有需要要就进行阅读

也希望对您有帮助,和您一起通关算法!致谢

万物的算法日记|第三天

算法语言:java
题目来源:力扣–书本–初级算法,可以在力扣中搜索相关题名找到更多解法和大神方法
本文知识点:

  1. 使用LInkedList模拟栈
    因为LInkedList内实现了栈数据结构的所有基本方法,例如addLast(),removeLast()等,同时也支持在任意位置进行插入,删除和读取操作。

addLast(E e):将元素添加到链表末尾,相当于将元素压入栈顶。
removeLast():从链表末尾删除一个元素,相当于弹出栈顶元素。
getLast():获得链表末尾的元素,相当于读取栈顶元素。 创建栈:

LinkedList<Integer> stack = new LinkedList<>(); 创建栈,
stack.addLast(1); 将1入栈
int top = stack.removeLast(); 将 1出栈,并赋值给 top
int top = stack.getLast(); 获得栈顶元素,即 1
stack.add(1, 4); 在栈中的第二个位置插入元素 4
stack.remove(1);删除栈中的第二个元素

  1. 哈希表的简单使用
    为什么会想到使用哈希表解决?
    原因:我们要保证复制出来的新链表中节点的random指针指向正确,需要使用一种方法来将原链表中的每个节点与其新表中对应的节点建立映射关系,方便后续在复制random时,找到对应关系
    哈希表:适合存储键值对对应关系,适用场景:快速查找,增删操作,当数据规模大的时候,性能优于数组和链表
  2. 学会使用StringBuilder对字符串类型进行处理
    什么是StringBuilder: 具有修改String的能力,相对于直接使用String对象,避免了不必要的内存开销
    适用场景:需要频繁对字符串拼接或者修改的情况下使用,避免了频繁创建对象的开销,性能更好
    方法:
    StringBuilder(): 无参构造方法,创建一个空的StringBuilder对象
    appen():向StringBuilder对象的末尾添加指定的数据
    insert() 向指定位置插入数据
    delete() 删除指定位置的数据
    replace() 替换指定位置的数据
    reverse() 将对象中的顺序颠倒
    lenth() 获取StringBuilder对象中的长度

切记:最后需要转化成对应的输出类型。:

详细可针对具体题目具体分析~~

剑指Offer06.从尾到头打印链表

万物的算法日记|第三天
代码:

public class day6_14_0_update {
    //递归思路 递归到尾部 然后进行回溯
    //代码非常的简单,而且也容易理解
    ArrayList<Integer> tmp = new ArrayList<>();
    public int[] reversePrint(ListNode head){
        recur(head);
        int[] res = new int[tmp.size()];
        for(int i =0;i<res.length;i++)
            res[i] = tmp.get(i);
        return res;
    }
    //通过递归到链表尾部,如果是空的话,就一层一层回溯,就实现了将尾部值依次添加到链表中
    public void recur(ListNode head){
        if(head == null)
            return;
        recur(head.next);
        tmp.add(head.val);
    }
//-------------------------------------------------------------------
    //使用辅助栈来 栈的特性 先进后出 使用LinkedList 来模拟栈
    public int[] reversePrint1(ListNode head){
        LinkedList<Integer> stack = new LinkedList<Integer>();
        while(head != null){
            stack.addLast(head.val);
            head = head.next;
        }
        int [] res = new int[stack.size()];
        for(int i =0;i<res.length;i++){
            res[i] = stack.removeLast();
        }
        return res;
    }
}

学到的知识:

  1. 之前的文章也说过了ArrayList和LInked的底层原理区别和对应的适用场景。
    通过LInkedList模拟栈,因为LInkedList内实现了栈数据结构的所有基本方法,例如addLast(),removeLast()等,同时也支持在任意位置进行插入,删除和读取操作。

addLast(E e):将元素添加到链表末尾,相当于将元素压入栈顶。
removeLast():从链表末尾删除一个元素,相当于弹出栈顶元素。
getLast():获得链表末尾的元素,相当于读取栈顶元素。 创建栈:

LinkedList<Integer> stack = new LinkedList<>(); 创建栈,
stack.addLast(1); 将1入栈
int top = stack.removeLast(); 将 1出栈,并赋值给 top
int top = stack.getLast(); 获得栈顶元素,即 1
stack.add(1, 4); 在栈中的第二个位置插入元素 4
stack.remove(1);删除栈中的第二个元素

剑指Offer24.反转链表

万物的算法日记|第三天
代码:


public class day6_14_1 {
    //反转链表
    //遍历 : 从头开始 直接修改指针指向
    public ListNode reverseList(ListNode head){
        ListNode cur = head,pre = null;
        while(cur!= null){
            ListNode temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur= temp;
        }
        return pre;
    }

    //递归回溯
    public ListNode reverseList1(ListNode head){
        return recur(head,null);
    }
    public ListNode recur(ListNode cur,ListNode pre){
        if(cur == null) return pre; //终止条件
        ListNode res = recur(cur.next,cur); //递归后继节点
        cur.next = pre; // 修改节点引用指向
        return res;  // 返回反转链表的头节点
    }

}

学到的知识:

  1. 递归的简单入门,递归的思路很简洁,要代码实现正确难一点,需要多练习和理解

剑指 Offer 35. 复杂链表的复制

万物的算法日记|第三天
首先我们先看一下简单的链表复制操作:

//简单的链表复制
    public Node copyEasyList(Node head){
        Node cur = head;
        Node dum = new Node(0),pre = dum;
        while(cur != null){
            Node node = new Node(cur.val);
            pre.next = node;
            cur = cur.next;
            pre = node;
        }
        return dum.next;
    }

理解了这一步,对于下面的复杂链表复制,只需要搞懂两个循环内部意思即可
代码:

/*
// Definition for a Node.
class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}
*/
class Solution {
    public Node copyRandomList(Node head){
        if(head == null){
            return null;
        }
        Node cur = head;
        //使用哈希表来进行存储节点信息
        Map<Node,Node> map = new HashMap<Node,Node>();
        //复制各节点,并建立 原节点- 新节点的map映射
        while(cur != null){
            map.put(cur,new Node(cur.val));
            cur =cur.next;
        }
        cur = head;
        while(cur != null){
            map.get(cur).next = map.get(cur.next);
            map.get(cur).random = map.get(cur.random);
            cur =cur.next;
        }
        return map.get(head);
    }
}

学到的知识点: 这题感觉挺难的,对我而言 哈哈

  1. 我之前错误的认为链表中的两个元素之间的指向是真实存在的哈哈,其实只是为了方便假象的。对于第二个while循环内的随机数赋值操作,其实可以理解成 赋值后就完成了对应的指针指向。
  2. 为什么会想到使用哈希表解决?
    原因:我们要保证复制出来的新链表中节点的random指针指向正确,需要使用一种方法来将原链表中的每个节点与其新表中对应的节点建立映射关系,方便后续在复制random时,找到对应关系
    哈希表:适合存储键值对对应关系,适用场景:快速查找,增删操作,当数据规模大的时候,性能优于数组和链表

剑指Offer 05.替换空格

万物的算法日记|第三天
代码:

public class day6_14_3 {
    // 拆分字符,遇见空格替换 时间复杂度为O(n)
    public String replaceSpace(String s){
        String a ="";
        for(int i =0;i<s.length();i++){
            if(s.charAt(i) == ' '){
                a+="%20";
                continue;
            }
            a+=s.charAt(i);
        }
        return a;
    }
    //使用 StringBuilder 来进行修改
    public String replaceSpace1(String s){
        StringBuilder res = new StringBuilder();
        for(Character c: s.toCharArray()){
            if(c == ' ')
                res.append("%20");
            else
                res.append(c);
        }
        return res.toString();
    }
    //直接使用API中的方法
    public String replaceSpace2(String s){
        return s.replace(" ","%20");
    }
}

学到的知识:

  1. s.charAt(i) 可以提取字符串中的固定位置字符
  2. 学会使用StringBuilder对字符串类型进行处理
    什么是StringBuilder: 具有修改String的能力,相对于直接使用String对象,避免了不必要的内存开销
    适用场景:需要频繁对字符串拼接或者修改的情况下使用,避免了频繁创建对象的开销,性能更好
    方法:
    StringBuilder(): 无参构造方法,创建一个空的StringBuilder对象
    appen():向StringBuilder对象的末尾添加指定的数据
    insert() 向指定位置插入数据
    delete() 删除指定位置的数据
    replace() 替换指定位置的数据
    reverse() 将对象中的顺序颠倒
    lenth() 获取StringBuilder对象中的长度

切记:最后需要转化成对应的输出类型。

  1. 记住一些API自带的一些方法,可以省去很多时间,s.replace(" “,”%20"),将A替换成B

剑指 Offer 58 II. 左旋转字符串

万物的算法日记|第三天

代码:


public class day6_14_4 {
    //简陋的实现方法 时间复杂度高
    public String reverseLeftWords(String s,int n){
        String a = "";
        String b = "";
        for(int i =0;i<n;i++){
            a += s.charAt(i);
        }
        b = s.replace(a,"");
        return b+a;
    }
    //使用StringBuilder
    public String reverseLeftWords1(String s ,int n){
        StringBuilder sh = new StringBuilder(s);
        for(int i =0;i<n;i++){
            sh.append(s.charAt(i));
            sh.deleteCharAt(0);
        }
        return  sh.toString();
    }
    //利用字符串切割操作
    public String reverseLeftWords2(String s,int n){
        return s.substring(n,s.length())+s.substring(0,n);
    }
}

学到的知识:文章来源地址https://www.toymoban.com/news/detail-484175.html

  1. 可以使用字符串自带的方法去切割,使用StringBuilder()来进行添加修改,以及使用列表或者二倍字符串来进行分隔等等,都可以实现,当做练手题目。

到了这里,关于万物的算法日记|第三天的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法训练第三天|203.移除链表元素、707.设计链表、206.反转链表

    题目链接:力扣 思路:删除链表元素与数组不同之处在于,它需要被删除链表元素的前一个元素和后一个元素的参与,而不需要其他元素的参与。 我们使被删除元素前一个元素的指针指向被删除元素的后一个元素 ,也就是直接跳过被删除的元素,来实现删除。 同时我们考

    2024年02月05日
    浏览(40)
  • QT第三天

    完善对话框,点击登录对话框,如果账号和密码匹配,则弹出信息对话框,给出提示”登录成功“,提供一个Ok按钮,用户点击Ok后,关闭登录界面,跳转到其他界面如果账号和密码不匹配,弹出错误对话框,给出信息”账号和密码不匹配,是否重新登录“,并提供两个按钮Y

    2024年02月03日
    浏览(38)
  • 计算机网络---第三天

                                                        OSI参考模型与TCP/IP模型 背景:①兼容性较差,接口不统一            ②不利于排错与维护            ③设备成本高 概念:OSI参考模型定义了网络中设备所遵守的层次结构 优点:①开放的

    2024年04月13日
    浏览(37)
  • WebAPIs 第三天

    DOM 事件进阶 事件流 事件委托 其他事件 元素尺寸与位置 事件流与两个阶段说明 事件捕获 事件冒泡 阻止冒泡 解绑事件 1.1 事件流与两个阶段说明 ① 事件流:指的是事件完整执行过程中的流动路径 ② 事件流分为捕获阶段和冒泡阶段  1.2 事件捕获 从DOM根元素开始去执行对

    2024年02月13日
    浏览(38)
  • 防御第三天

    1.总结当堂NAT与双机热备原理,形成思维导图    2.完成课堂NAT与双机热备实验 fw1: USG6000V1sy [USG6000V1]int g0/0/0 [USG6000V1-GigabitEthernet0/0/0]ip add 192.168.18.2 24 [USG6000V1-GigabitEthernet0/0/0]service-manage all permit (地址无所谓,能通就行):         fw2: USG6000V1sy [USG6000V1]int g0/0/0 [USG6000V1-Giga

    2024年02月15日
    浏览(52)
  • 前端之css第三天

    CSS的盒子模型是用来描述HTML元素在页面中的布局和排列方式的一种模型。每个HTML元素都可以被看作是一个矩形的盒子,这个盒子由四个可调整大小的部分组成:内容区域、内边距区域、边框区域和外边距区域。 内容区域(content area):此区域存放元素的实际内容,例如文本

    2024年02月22日
    浏览(36)
  • 实习记录——第三天

    今天还是去学习,昨天看另一个实习生有在了解ctf什么的,我就打算也看一看,问了问我的导师,他说我闲了可以看看,把我拉到了公司的ctf组,本来以为会是什么高大上的组织,结果好像就是平时分享分享知识,偶尔打个比赛,今天加进去,一天没任何动静。 简单看了看导

    2024年01月25日
    浏览(47)
  • python基础第三天

    s=‘hello’ sio=io.StringIO(s) sio.getValue() ‘hello’ sio.seek(3) sio.write(‘a’) sio.getValue() ‘helao’ 按位或| 只要有一个是1就是1 按位与 两个都是1才是1 按位异或^ 一个是1一个是0才是1,不相同才是1 22 =2 2 2=2*4 左移1位 81 =8/2=4 python里没有自增a++ 自减a– 位运算符和算数运算符比较运算符

    2024年02月08日
    浏览(35)
  • 代码随想录第三天

    链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。 链表的入口节点称为链表的头结点也就是head。 单链表 与上面所说一致。 单链表中的指针

    2024年02月04日
    浏览(41)
  • Day 3 打卡第三天

    给你一个链表的头节点  head  和一个整数  val  ,请你删除链表中所有满足  Node.val == val  的节点,并返回  新的头节点  。  示例 1: 示例 2: 示例 3: 提示: 列表中的节点数目在范围  [0, 104]  内 1 = Node.val = 50 0 = val = 50 目标值在链表开头需特判,搞清楚逻辑关系 有点多

    2024年02月07日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包