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

力扣-数据结构-3【算法学习day.74】

前言

###我做这类文章一个重要的目的还是给正在学习的大家提供方向(例如想要掌握基础用法,该刷哪些题?建议灵神的题单和代码随想录)和记录自己的学习过程,我的解析也不会做的非常详细,只会提供思路和一些关键点,力扣上的大佬们的题解质量是非常非常高滴!!!


习题

1.反转偶数长度组的节点

题目链接:2074. 反转偶数长度组的节点 - 力扣(LeetCode)

题面:

 分析:用数组存值的同时再开一个falg数组存一下每个节点所属的组,对于非最后一组来说,如果是偶数组,那么该组个数也是偶数个,进行翻转,对于最后一组,提前统计最后一组的个数,如果为偶数,就进行反转,反转过程中使用虚拟头节点更方便

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseEvenLengthGroups(ListNode head) {
        int[] arr = new int[100005];
        int[] flag = new int[100005];
        int inz = 1;
        int index = 1;
        int count = 1;
        for(ListNode i = head;i!=null;i = i.next){
            flag[index] = inz;
            arr[index++] = i.val;
            if(count==inz){
                count = 1;
                inz++;
            }else{
                count++;
            }
        }
        int blag = flag[index-1];
        int lastcount = 1;
        for(int i = index-2;i>=1&&flag[i]==blag;i--)lastcount++;
        ListNode fhead = new ListNode(-1);
        fhead.next = head;
        ListNode pre = fhead;
        index = 1;
        int left = 3;
        boolean firstin = true;
        // System.out.println(blag+"         "+lastcount);
        for(ListNode i = head;i!=null;i = i.next){
            if(flag[index]!=flag[index-1]){
                 firstin = true;
            }
            if((flag[index]%2==0&&flag[index]!=blag)||(flag[index]==blag&&lastcount%2==0)){
                if(firstin){
                    if(flag[index]==blag){
                        left = index+lastcount-1;
                    }else{
                        left = index+flag[index]-1;
                    }
                     firstin = false;
                }
                ListNode node = new ListNode(arr[left--]);
                pre.next = node;
                pre = node;
            }
            else{
                pre.next = i;
                pre = i;
            }
            index++;
         }
         return fhead.next;
    }
}

2.旋转链表

题目链接:61. 旋转链表 - 力扣(LeetCode)

题面:

分析:可以通过计算出向右移动k个位置的头节点的值,然后遍历时,维护一个变量用于记录遍历当前节点的上一个节点(这里开一个虚拟头节点可以少一些考虑),当遍历到目标头节点时,让目标头节点的上一个节点指向空,然后遍历到的最后一个节点指向原头节点即可

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode rotateRight(ListNode head, int k) {
        if(head==null)return null;
        int count = 0;
        for(ListNode i = head;i!=null;i=i.next){
            count++;
        }
        int flag = k%count;
        int bindex = count-flag+1;
        int index = 1;
        ListNode fhead = new ListNode();
        fhead.next = head;
        ListNode pre = fhead;
        ListNode ans = null;
        for(ListNode i = head;i!=null;i =i.next){
            if(index==bindex){
                ans = i;
                ListNode node = null;
                pre.next = node;
            }
            if(index==count){
                i.next = fhead.next;
            }
            pre = i;
            index++;
        }
        return ans;
    }
}

3.交换链表中的节点

题目链接: 1721. 交换链表中的节点 - 力扣(LeetCode)

题面:

分析:找到正数和倒数两个节点的索引位置,并存一下值,这里用递归比较方便,然后遍历链表修改值

代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    ListNode head;
    int k;
    int zval = -1;
    int rval = -1;
    int r = 0;
    public ListNode swapNodes(ListNode head, int k) {
        this.head = head;
        this.k = k;
        recursion(head,1);
        int index = 1;
        for(ListNode i = head;i!=null;i=i.next){
            if(index==k){
                i.val = rval;
            }else if(index==r){
                i.val = zval;
            }
            index++;
        }
        return head;
    }
    public int recursion(ListNode node,int z){
        if(node==null)return 1;
        if(z==k){
            zval = node.val;
        }
        int r2 = recursion(node.next,z+1);
        if(r2==k){
            rval = node.val;
            r = z;
        }
        return r2+1;
    }
}

4.链表的中间节点

题目链接:876. 链表的中间结点 - 力扣(LeetCode)

题面:

分析:可以用递归分别统计节点的个数和答案节点的索引,在回溯过程中如果回溯到答案节点,返回

代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    int flag = -1;
    ListNode ans = null;
    public ListNode middleNode(ListNode head) {
        recursion(head,1);
        return ans;
    }
    public void recursion(ListNode node,int z){
        if(node==null){
            flag =(z-1)/2+1;
            return;
        }
        recursion(node.next,z+1);
        if(z==flag){
            ans = node;
            return;
        }
    }
}

5.删除链表的中间节点

题目链接: 2095. 删除链表的中间节点 - 力扣(LeetCode)

题面:

分析:快慢指针,慢指针每次走一步,快指针每次走两步,当快指针指向的位置是最后一个节点或者是null,此时慢指针更好指向中间节点,然后正常删除就行

代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode deleteMiddle(ListNode head) {
        if(head==null||head.next==null)return null;
        ListNode pre = head;
        for(ListNode i = head ,j=head;i!=null;i=i.next){
            if(j==null||j.next==null){
                ListNode node = i.next;
                pre.next = node;
                break;
            }      
            j=j.next.next;
            pre = i;
        }
        return head;
    }
}

6.回文链表

题目链接:234. 回文链表 - 力扣(LeetCode)

题面:

分析:使用StringBuilder的reverse方法

代码:

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        StringBuilder sb = new StringBuilder();
        for(ListNode i = head;i!=null;i=i.next){
            sb.append(i.val+"");
        }
        // System.out.println(sb.reverse().toString());
        // System.out.println(sb.toString());
        return sb.toString().equals(sb.reverse().toString());
    }
}

后言

上面是力扣数据结构相关,下一篇是其他的习题,希望有所帮助,一同进步,共勉!

 

 

 

 

 


http://www.kler.cn/a/453147.html

相关文章:

  • 如何在机房里脱困(下)
  • 初始 ShellJS:一个 Node.js 命令行工具集合
  • Linux -- 互斥的底层实现
  • 医疗平板与普通平板对比:优势尽显
  • linux RCU调优
  • 《Cocos Creator游戏实战》非固定摇杆实现原理
  • 存储块的获取与释放
  • Windows下ESP32-IDF开发环境搭建
  • 智源研究院与安谋科技达成战略合作,共建开源AI“芯”生态
  • 冰狐智能辅助使用插件化开发集成三方ocr
  • Linux中的lseek 函数与fcntl函数
  • CMS(Concurrent Mark Sweep)垃圾回收器的具体流程
  • 使用Python读写文本文件
  • 【2024最新】基于Python+Mysql+django的水果销售系统Lw+PPT
  • 网络层协议--ip协议
  • uni-app 中使用微信小程序第三方 SDK 及资源汇总
  • 常用的Django模板语言
  • 437 路径总和III
  • 接口调用限频(代理模式+滑动窗口)
  • Electron【详解】菜单 Menu
  • tokenizer、tokenizer.encode、tokenizer.encode_plus比较
  • 打造两轮差速机器人fishbot:从零开始构建移动机器人
  • 前端开发 -- 自动回复机器人【附完整源码】
  • 如何检查交叉编译器gcc工具链里是否有某个库(以zlib库和libpng库为例)
  • 修炼之道 ---其四
  • 3.系统学习-熵与决策树