首页 > 其他分享 >经典数据结构题目-链表

经典数据结构题目-链表

时间:2024-01-14 23:56:05浏览次数:27  
标签:index head ListNode int next 链表 题目 数据结构

链表

707. 设计链表

  • 解题思路

    • 参考官方的单向链表,设置一个成员变量作为虚拟头节点,一个成员变量size保存有效节点数
  • 代码

public MyLinkedList() {
  size = 0;
  head = new ListNode(0);
}


public int get(int index) {
  if (index < 0 || index >= size) {
    return -1;
  }
  // 借助虚拟头节点,可以较为方便地获取到index对应的节点
  ListNode cur = head;
  for (int i = 0; i <= index; i++) {
    cur = cur.next;
  }
  return cur.val;
}

public void addAtHead(int val) {
  addAtIndex(0, val);
}

public void addAtTail(int val) {
  addAtIndex(size, val);
}

public void addAtIndex(int index, int val) {
    if (index > size) {
      return;
    }
    index = Math.max(0, index);
    size++;
  	// 定位到插入位置的前一个元素
    ListNode pred = head;
    for (int i = 0; i < index; i++) {
      pred = pred.next;
    }
  	// 插入元素
    ListNode toAdd = new ListNode(val);
    toAdd.next = pred.next;
    pred.next = toAdd;
}

public void deleteAtIndex(int index) {
  if (index < 0 || index >= size) {
    return;
  }
  size--;
  // 定位到删除位置的前一个
  ListNode pred = head;
  for (int i = 0; i < index; i++) {
    pred = pred.next;
  }
  // 删除元素
  pred.next = pred.next.next;
}

206. 反转链表

解法一

  • 思路

    • 快慢指针进行遍历,快指针先存下当前节点的next,再将next指向slow的。两指针再一起往前移动
  • 代码

    public ListNode reverseList(ListNode head) {
        ListNode fast = head;
        ListNode slow = null;
        while(fast != null){
            ListNode next = fast.next;  // 注意点一
            fast.next = slow;
            slow = fast;
            fast = slow;
        }
        return last;
    }
  • 注意点
    • 注意点一:操作链表时,修改next指针时,注意是否需要保存下来,防止找不到了

解法二

  • 思路
    • 使用递归
      • 终止条件。只剩下一个节点,节点为空
      • 递归参数。入参 ,需要反转的链表头;出参,反转后的头
      • 当前层处理。接入到反转后的链表尾,next指针指向空
  • 代码
 public ListNode reverseList(ListNode head) {
   			// 终止条件
        if (head == null || head.next == null) return head;
   			// 递归
        ListNode p = reverseList(head.next);
   			// 当前层处理
        head.next.next = head;
        head.next = null;
        return p;
    }

92. 反转链表 II

解法一

  • 思路

    • 通过一次遍历,定位出反转 开始 和 结束 关键的四个节点
    • 遍历的过程,对left和right区间的进行反转
    • 最后再根据四个关键节点进行重新拼接
  • 代码

    •     public ListNode reverseBetween(ListNode head, int left, int right) {
              // 定位出四个关键节点
              ListNode leftBefore = null;
              ListNode leftNode = null;
              ListNode rightAfter = null;
              ListNode rightNode = head; // 注意点一
      
              // 定位四个关键节点同时进行反转
              ListNode fast = head;
              ListNode slow =null;
              int index = 1;
              while(index <= right){
                  ListNode next = fast.next;
                  // 记录下反转开始
                  if(index == left){
                      leftBefore = slow;
                      leftNode = fast;
                  }
                  // 开始进行反转
                  if(index >= left){
                      fast.next = slow;
                  }
                  // 快慢指针移动
                  slow = fast;
                  fast = next;
                  index ++;            
              }
              rightAfter = fast;
              rightNode = slow;
      
              // 四个关键节点进行重新拼接
              leftNode.next = rightAfter;
              if(leftBefore == null){ // 注意点二
                  return rightNode;
              }
              leftBefore.next = rightNode;
              return head;
          }
      
  • 注意点

    • 注意点一:因为结果将rightNode作为头返回,当只有一个元素时且要进行反转时,需要将原头节点返回
    • 注意点二:left从1开始时,会导致leftBefore为空

解法二

  • 思路
    • 递归
      • 终止条件。当left等于1时,以当前为头的N个元素进行反转即可。可参考反转链表题
      • 递归参数。入参,以下一个节点为头的链表,因为少了一个元素,反转的位置都减一。出参,反转后的链表头
      • 当前层处理。头的next指针指向新的链表头
  • 代码
    ListNode afterN = null;

      public ListNode reverseBetween(ListNode head, int left, int right) {
          if(left == 1){
              return reverseN(head,right);
          }
          head.next = reverseBetween(head.next,left-1,right-1);
          return head;
      }

      public ListNode reverseN(ListNode head, int n){
          if(n == 1){
              afterN = head.next; //注意点一
              return head;
          }
          ListNode newHead = reverseN(head.next, n-1);
          head.next.next = head;
          head.next = afterN; 
          return newHead;
      }
  • 注意点
    • 注意点一。反转N个元素后,这N个元素可能是在原本链表的中间,需要记录下来,待整个反转后重新接回

标签:index,head,ListNode,int,next,链表,题目,数据结构
From: https://www.cnblogs.com/gg12138/p/17964481

相关文章

  • 数据结构-------单链表
    单链表:在计算机科学中,链表是数据元素的线性组合,元素储存上并不连续。可以分为:单向链表、双向链表、循环链表 单向链表:首先,定义结点的类型,它包括值和下一个结点 相关java代码:1privateNodehead;//定义头部结点2publicclassNode{3privateint......
  • 01-链表
    目录一.单链表一.单链表通过链表添加/展示信息#include<stdio.h>#include<stdlib.h>/*链表结构体:data:表示学生成绩next:学生成绩结构体指针*/typedefstructNode_Student{intdata;structNode_Student*next;//这里不能直接写Node,虽然前......
  • NC66 两个链表的第一个公共结点
    https://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?tpId=117&rp=1&ru=%2Fexam%2Foj&qru=%2Fexam%2Foj&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E7%25AE%2597%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D117&difficulty=&j......
  • 记一次docker出全linux的内网渗透题目(仿照2023铸剑杯)
    前言在2023年末的时候参加了一个铸剑杯,这个比赛主要是渗透和实网攻防,仿照这个比赛的历程做了个渗透靶场(环境与铸剑杯有很大区别,这里只有三层(因为我比较菜,只做出来了两层))顺便学习一下dockergithub下载然后运行startup.sh就可以自动搭建了使用https://www.itsvse.com/do......
  • 开发日志(数据结构、时间戳、javaException)
     (一)数据库类型mysql中的datetime可以转为postgres的date(二)数据库时间戳postgresql使用时间戳获取时分秒时间1、selectcurrent_timestamp2024-01-1214:16:31.93339+082、selectcurrent_timestamp(0) //去掉秒后面的位数,但仍有时区2024-01-1214:17:42+083、CURRENT_TIMESTAMP(......
  • css相关题目
    1、元素居中 水平居中:      行内元素:text-align:center;      块级元素:                    已知宽度:margin:0auto;绝对定位+margin-left:(父盒子width–子盒子width)/2        未知宽度:display:inline......
  • Oracle查询多种数据结构并计算合计值
    数据情况:   一、造数、建表结构 --auto-generateddefinitioncreatetableTREETEST(BIZ_DATEVARCHAR2(8),C_ZHDMVARCHAR2(50),PF_NAMEVARCHAR2(100),SYMBOL_CODEVARCHAR2(50),CYZC_IDVA......
  • 数据结构之【栈】
    栈和队列是线性表的两个经典特例,它们都是操作受限的线性表,即操作位置需要满足各自的条件,因为这些条件的特殊性,使得实现各自的操作时过程简捷,效率更高。这两个数据结构的应用也非常广泛。栈自助餐厅里的一摞盘子就是常见的栈的例子。在栈中,只能在栈顶位置添加或删除数据项。排队是日......
  • 学生管理系统单链表
    #include"stdio.h"#include"stdlib.h"#include"string.h"#defineRD_NO(1<<0)#defineRD_NAME(1<<1)#defineRD_SEX(1<<2)#defineRD_SCORE(1<<3)//描述1个学生的属性structSTUDENT{......
  • 学生管理系统双链表
    #include"stdio.h"#include"stdlib.h"#include"string.h"#defineRD_NO(1<<0)#defineRD_NAME(1<<1)#defineRD_SEX(1<<2)#defineRD_SCORE(1<<3)//描述1个学生的属性structSTUDENT{......