力扣-数据结构-1【算法学习day.72】

前言

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


这几天今天复习一下数据结构

习题

1.二进制链表转整数

题目链接: 1290. 二进制链表转整数 - 力扣(LeetCode)

题面:

**分析:**遍历链表,然后开一个变量,每次左移一位再加上链表上的值即可

代码:

java 复制代码
/**
 * 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 int getDecimalValue(ListNode head) {
        int sum = 0;
        for(ListNode i = head;i!=null;i=i.next){
           sum<<=1;
           sum+=i.val;
        }
        return sum;
    }
}

2. 找出临界点之间的最小和最大距离

题目链接: 2058. 找出临界点之间的最小和最大距离 - 力扣(LeetCode)

题面:

**分析:**我们可以定义三个变量分别记录最开始的节点索引,上一个的索引,和最后的索引,那么最小距离就是在找到一个索引后,取ans[0]和当前索引与记录的上一个节点的索引的最小值,最大值就是最后一个索引与第一个索引的超值

代码:

java 复制代码
/**
 * 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[] ans = new int[]{Integer.MAX_VALUE,-1};
    public int[] nodesBetweenCriticalPoints(ListNode head) {
        int start = -1;
        int end = -1;
        int pre = -1;
        int count = 0;
        int index = 0;
        for(ListNode i =  head;i!=null&&i.next.next!=null;i=i.next){
            index++;
            int a = i.val;
            int b = i.next.val;
            int c = i.next.next.val;
            if(b>a&&b>c){ 
                count++;
                if(count==1)start = index;
                if(index>1)ans[0] = Math.min(ans[0],index - pre);
                pre = index;
            }
            else if(b<a&&b<c){
                count++;
                if(count==1)start = index;
                if(index>1)ans[0] = Math.min(ans[0],index - pre);
                pre = index;
            }
        }
        if(count<2)return new int[]{-1,-1};
        ans[1] = pre - start;
        return ans;
    }
}

3.合并零之间的节点

题目链接: 2181. 合并零之间的节点 - 力扣(LeetCode)

题面:

**分析:**这题遍历链表,定义一个变量sum来计算和值,如果下一个是0,就更新链表

代码:

java 复制代码
/**
 * 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 mergeNodes(ListNode head) {
        ListNode ans = new ListNode();
        ListNode node = new ListNode();
        ans.next = node;
        int sum = 0;
        int count= 0;
        for(ListNode i = head;i!=null;i=i.next){
            if(i.val==0)continue;
            sum+=i.val;
             if(i.next.val==0&&count==0){
                node.val = sum;
                sum = 0;
                count++;
            }else if(i.next.val==0){
                ListNode node2 = new ListNode();
                node2.val = sum;
                sum = 0;
                node.next = node2;
                node = node2;
            }
        }
        return ans.next;
    }
}

4. 分割链表

题目链接: 725. 分隔链表 - 力扣(LeetCode)

题面:

**分析:**这题主要看链表中节点的个数与k之间的数学关系,例如如果count/k==0,说明肯定不够分,那么就是将链表全分为单节点,如果>0,记flag = count/k,如果count%k!=0,为了迎合题意:任意两部分的长度差距不能超过1,且前面的长度大于后面的长度,则让前count%k的长度为flag+1

代码:

java 复制代码
/**
 * 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[] splitListToParts(ListNode head, int k) {
        ListNode[] ans = new ListNode[k];
        int count = 0;
        for(ListNode i = head;i!=null;i=i.next)count++;
        // System.out.println(count);
        int flag = count/k;
        if(flag==0){
            int index = 0;
            for(ListNode i = head;i!=null;i=i.next){
                 ListNode node = new ListNode(i.val);
                 ans[index++]  = node;
            }
        }else{
            int fcount = count%k;
            int index = 0;
            int gcount = 0;
            boolean su = false;
            ListNode fhead = head;
            for(ListNode i = head;i!=null||((i==null)&&su);i=i.next){
                 if(su){
                    i = fhead;
                    su = false;
                 }
                 gcount++;
                 if(fcount>0&&gcount%(flag+1)==0){
                       ListNode node = i;
                       i = i.next;
                       su = true;
                       node.next = null;
                       ans[index++] = fhead;
                       fhead = i; 
                       gcount = 0;
                       fcount--;
                 }else if(fcount==0&&gcount%flag==0){
                        ListNode node = i;
                       i = i.next;
                       su = true;
                       node.next = null;
                       ans[index++] = fhead;
                       fhead = i; 
                       gcount = 0;
                 }
                 if(i==null)break;
                 
            }
        }
        return ans;
    }
}

5.链表组件

题目链接: 817. 链表组件 - 力扣(LeetCode)

题面:

**分析:**哈希表

代码:

java 复制代码
/**
 * 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 int numComponents(ListNode head, int[] nums) {
        Map<Integer,Integer> map = new HashMap<>();
        for(int a:nums){
            map.put(a,1);
        }
        int ans = 0;
        int count = 0;
        for(ListNode i = head;i!=null;i = i.next){
            if(map.getOrDefault(i.val,-1)==1){
                count++;
                continue;
            }else{
                if(count>0){
                    ans++;
                    count = 0;
                }
            }
        }
        if(count>0)ans++;
        return ans;
    }
}

6.移除链表元素

题目链接: 203. 移除链表元素 - 力扣(LeetCode)

题面:

**分析:**定义一个虚拟头结点会简单些

代码:

java 复制代码
/**
 * 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 removeElements(ListNode head, int val) {
        ListNode fhead  = new ListNode();
        fhead.next = head;
        ListNode pre = fhead;
        for(ListNode i = head;i!=null;i = i.next){
            if(i.val==val){
                pre.next = i.next;
            }else{
                pre = i;
            }
        }
        return fhead.next;
    }
}

7.从链表中移除在数组中存在的节点

题目链接: 3217. 从链表中移除在数组中存在的节点 - 力扣(LeetCode)

题面:

**分析:**在上一题的基础上加个哈希表

代码:

java 复制代码
/**
 * 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 modifiedList(int[] nums, ListNode head) {
        Map<Integer,Integer> map = new HashMap<>();
        for(int a:nums){
            map.put(a,1);
        }
        ListNode fhead = new ListNode();
        fhead.next = head;
        int count = 0;
        ListNode pre = fhead;
        for(ListNode i = head;i!=null;i = i.next){
            if(map.getOrDefault(i.val,-1)==1){
                pre.next = i.next;
            }else{
                pre = i;
            }
        }
        return fhead.next;
    }
}

8.删除排序链表中的重复元素

题目链接: 83. 删除排序链表中的重复元素 - 力扣(LeetCode)

题面:

**分析:**和上面题类似

代码:

java 复制代码
/**
 * 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 deleteDuplicates(ListNode head) {
        ListNode fhead = new ListNode(Integer.MIN_VALUE);
        fhead.next = head;
        ListNode pre = fhead;
        for(ListNode i = head;i!=null;i = i.next){
            if(i.val == pre.val){
                pre.next = i.next;
            }else{
                pre = i;
            }
        }
        return fhead.next;
    }
}

9.删除排序链表中的重复元素II

题目链接: 82. 删除排序链表中的重复元素 II - 力扣(LeetCode)

题面:

**分析:**这题有许多小问题需要考虑,值得细做

代码:

java 复制代码
/**
 * 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 deleteDuplicates(ListNode head) {
        ListNode fhead = new ListNode(Integer.MAX_VALUE);
        fhead.next = head;
        ListNode pre = fhead;
        ListNode flag = fhead;
        int count = 1;
        boolean su  = false;
        for(ListNode i = head;i!=null;i = i.next){
            su = false;
            if(i.val!=pre.val&&count>=2){
                flag.next = i;
                count = 1;
                su = true;
            }else if(i.val==pre.val){
                count++;
            }
            if(i.val!=head.val&&i.val!=pre.val&&!su){
                flag = pre;
            }
            pre = i;
        }
        if(count>=2)flag.next = null;
        return fhead.next;
    }
}

10.删除链表中的节点

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

题面:

**分析:**让node等于node的下一个节点的值,以此类推,但题目需要链表长度减一,那么倒数第二个节点应该指向null,如果i.next.next==null,说明此时遍历到的i就是倒数第二个节点

代码:

java 复制代码
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public void deleteNode(ListNode node) {
        for(ListNode  i = node;i!=null;i=i.next){
             i.val = i.next.val;
             if(i.next.next==null){
               i.next = null;
                break;
            }
        }
    }
}

11.合并两个链表

题目链接: 1669. 合并两个链表 - 力扣(LeetCode)

题面:

代码:

java 复制代码
/**
 * 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 mergeInBetween(ListNode list1, int a, int b, ListNode list2) {
        ListNode fhead = new ListNode();
        fhead.next = list1;
        ListNode pre = fhead;
        int index = 0;
        boolean su = true;
        for(ListNode i = list1;i!=null;i=i.next){
             if(index==a){
                su = false;
             }
             if(su)pre = i;
             if(index==b){
                pre.next = list2;
                for(ListNode j = list2;j!=null;j = j.next){
                    if(j.next==null){
                        j.next = i.next;
                        break;
                    }
                }
                break;
             }
             index++;
        }
        return fhead.next;
    }
}

12.从链表中移除节点

题目链接: 2487. 从链表中移除节点 - 力扣(LeetCode)

题面:

**分析:**首先将链表中的值存到数组里去,然后从后往前遍历数组,并不断更新当前索引右边数字集合的最大值,如果当前索引所对应的值小于最大值,那么将当前位置标记成一个值(不在节点取值范围内),如果大于,就更新最大值,然后遍历链表,将标记的位置的节点删掉就行

代码:

java 复制代码
/**
 * 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 mu = 100005;
    public ListNode removeNodes(ListNode head) {
        int[] arr = new int[100005];
        int count = 0;
        for(ListNode i = head;i!=null;i=i.next){
            arr[count++] = i.val;
        }
        int max = arr[count-1];
        for(int i = count-2;i>=0;i--){
            if(arr[i]<max){
                arr[i] = mu;
            }else{
                max = arr[i];
                arr[i] = 0;
            }
        }
        ListNode fhead = new ListNode();
        fhead.next = head;
        ListNode pre  = fhead;
        int index = 0;
        for(ListNode i = head;i!=null;i=i.next){
            if(arr[index++]==mu){
                pre.next = i.next;
            }else{
                pre = i;
            }
        }
        return fhead.next;
    }
}

13.在链表中插入最大公约数

题目链接: 2807. 在链表中插入最大公约数 - 力扣(LeetCode)

题面:

**分析:**这里用到了辗转相除法快速求最大公约数

代码:

java 复制代码
/**
 * 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 insertGreatestCommonDivisors(ListNode head) {
        if(head.next==null)return head;
        for(ListNode i = head;i!=null;i=i.next.next){
            int val = gcd(i.val,i.next.val);
            ListNode node = new ListNode(val);
            ListNode next = i.next;
            i.next = node;
            node.next = next;
            if(i.next.next.next==null)break;
        }
        return head;
    }
    public int gcd(int a,int b){
        return b==0?a:gcd(b,a%b);
    }
}

14.循环有序列表的插入

题目链接: LCR 029. 循环有序列表的插入 - 力扣(LeetCode)

题面:

贴上大佬代码:

java 复制代码
class Solution {
    public Node insert(Node he, int x) {
        Node t = new Node(x);
        t.next = t;
        if (he == null) return t;
        Node ans = he;
        int min = he.val, max = he.val;
        while (he.next != ans) {
            he = he.next;
            min = Math.min(min, he.val);
            max = Math.max(max, he.val);
        }
        if (min == max) {
            t.next = ans.next;
            ans.next = t;
        } else {
            while (!(he.val == max && he.next.val == min)) he = he.next;
            while (!(x <= min || x >= max) && !(he.val <= x && x <= he.next.val)) he = he.next;
            t.next = he.next;
            he.next = t;
        }
        return ans;
    }
}

后言

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

相关推荐
数据小爬虫@24 分钟前
Java爬虫实战:深度解析Lazada商品详情
java·开发语言
咕德猫宁丶27 分钟前
探秘Xss:原理、类型与防范全解析
java·网络·xss
songroom27 分钟前
Rust: offset祼指针操作
开发语言·算法·rust
F-2H2 小时前
C语言:指针4(常量指针和指针常量及动态内存分配)
java·linux·c语言·开发语言·前端·c++
苹果酱05672 小时前
「Mysql优化大师一」mysql服务性能剖析工具
java·vue.js·spring boot·mysql·课程设计
axxy20002 小时前
leetcode之hot100---24两两交换链表中的节点(C++)
c++·leetcode·链表
chenziang13 小时前
leetcode hot100 环形链表2
算法·leetcode·链表
_oP_i3 小时前
Pinpoint 是一个开源的分布式追踪系统
java·分布式·开源
mmsx3 小时前
android sqlite 数据库简单封装示例(java)
android·java·数据库
武子康3 小时前
大数据-258 离线数仓 - Griffin架构 配置安装 Livy 架构设计 解压配置 Hadoop Hive
java·大数据·数据仓库·hive·hadoop·架构