Letcode-Top 100 简单题目

本文探讨了求两数之和的几种方法,包括暴力破解和HashMap优化,强调了预处理数据的重要性。同时,详细介绍了有效括号的判断,通过栈结构解析对称匹配。在链表专题中,讲解了合并两个有序链表、环形链表检测、相交链表查找、反转链表和回文链表的判断,展示了多种链表操作的高效解决方案。
摘要由CSDN通过智能技术生成

1. 两数之和

在这里插入图片描述

1.这道题目首先想到的是用暴力破解的方法

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] result = new int[2];
        // 循环
        for(int i=0;i<nums.length-1;i++){
            for(int j=i+1;j<nums.length;j++){
                if(nums[i]+nums[j]==target){
                    return new int[]{i,j};
                }
            }
        }
        return result;

    }
}

2.HashMap方法(本思路为,先将数组遍历存储到Map中,然后,在每次遍历查询的时候去掉自身的数据,这里需要注意的地方是,map.remove(key)是根据key删除,map.remover(key,value))是根据键值对删除。可能存在{3,3}这样的数据,所以删除的话,要用map.remove(key,value),否则,用map.remove(key)的话,会删除两个值。

/*使用存储空间  */
import java.util.Map;
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] result = new int[2];
        
        // 结果
        Map<Integer,Integer> map = new HashMap<>();
        for(int i=0;i<nums.length;i++){
            map.put(nums[i],i);
        }

        for(int i=0;i<nums.length;i++){
            map.remove(nums[i],i);

            if(map.containsKey(target-nums[i])){
                return new int[]{i,map.get(target-nums[i])};
            }
            map.put(nums[i],i);

        }

        return result;

    }
}

3.HashMap的优化方法 (Letcode官方解法,先查询后放到Map中)

/*使用存储空间  */
import java.util.Map;
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] result = new int[2];
        
        // 结果
        Map<Integer,Integer> map = new HashMap<>();
        for(int i=0;i<nums.length;i++){
            if(map.containsKey(target-nums[i])){
                return new int[]{i,map.get(target-nums[i])};
            }
            map.put(nums[i],i);

        }

        return result;

    }
}

20. 有效的括号

在这里插入图片描述

  • 这道题的核心思路是把逻辑梳理清楚

由于栈结构的特殊性,非常适合做对称匹配类的题目。
首先要弄清楚,字符串里的括号不匹配有几种情况。
一些同学,在面试中看到这种题目上来就开始写代码,然后就越写越乱。
建议要写代码之前要分析好有哪几种不匹配的情况,如果不动手之前分析好,写出的代码也会有很多问题。
先来分析一下 这里有三种不匹配的情况,
第一种情况,字符串里左方向的括号多余了 ,所以不匹配。 !括号匹配1
第二种情况,括号没有多余,但是 括号的类型没有匹配上。 !括号匹配2
第三种情况,字符串里右方向的括号多余了,所以不匹配。 !括号匹配3
我们的代码只要覆盖了这三种不匹配的情况,就不会出问题,可以看出 动手之前分析好题目的重要性。

动画如下:

1.常规逻辑

import java.util.Stack;
class Solution {
    public boolean isValid(String s) {

        // 首先对字符串进行拆分 
        char[] chars = s.toCharArray();
        Stack<Character> stack = new Stack<>();

        for(int i=0;i<chars.length;i++){
            if(chars[i]=='('||chars[i]=='{'||chars[i]=='['){
                 stack.push(chars[i]);
            }else{
                if(stack.isEmpty()||(!isMatch(stack.peek(),chars[i]))){
                    return false;
                }
                stack.pop();
            }
        }

        if(stack.isEmpty()){
            return true;
        }else{
            return false;
        }

    }


    public boolean isMatch(char left,char right){
        if(left=='('&&right==')'){return true;}
        if(left=='{'&&right=='}'){return true;}
        if(left=='['&&right==']'){return true;}
        return false;
    }
}

2.Letcode经典逻辑


import java.util.Stack;
class Solution {
    public boolean isValid(String s) {

        // 首先对字符串进行拆分 
        char[] chars = s.toCharArray();
        Stack<Character> stack = new Stack<>();

        for(int i=0;i<chars.length;i++){
            if(chars[i]=='('){
                stack.push(')');
            }else if(chars[i]=='{'){
                stack.push('}');
            }else if(chars[i]=='['){
                stack.push(']');
            }else {
                if(stack.isEmpty()){
                    return false;
                }
                if(stack.peek()==chars[i]){
                    stack.pop();
                }else{
                    return false;
                }
            }
        }

        if(!stack.isEmpty()){
           return false;
        }

       return true;

    }

}

《链表专题》

21. 合并两个有序链表

在这里插入图片描述
1.使用类似归并的算法

/**
 * 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 mergeTwoLists(ListNode list1, ListNode list2) {
        // 首先新建一个链表
        ListNode newList = new ListNode(0);
        ListNode pre = newList;
        if(list1==null){
            newList.next = list2;
        }

        if(list2==null){
            newList.next = list1;
        }

        while(list1!=null&&list2!=null){
            
            if(list1.val<list2.val){
                newList.next = list1;
                list1 = list1.next;
            }else{
                newList.next = list2;
                list2 = list2.next;
            }
            newList = newList.next;
        }

        if(list1!=null){
            newList.next = list1;
        }

        if(list2!=null){
            newList.next = list2;
        }


        return pre.next;

    }
}

2.递归方法(核心是递归方程)
在这里插入图片描述

/**
 * 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 mergeTwoLists(ListNode list1, ListNode list2) {
        if(list1==null){
            return list2;
        }else if(list2==null){
            return list1;
        }else if(list1.val>list2.val){
            list2.next = mergeTwoLists(list1,list2.next);
            return list2;
        }else{
            list1.next = mergeTwoLists(list1.next,list2);
            return list1;
        }

    }
}

141. 环形链表

在这里插入图片描述
1.暴力破解,超级无敌经典的方法

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {

        int count = 0;


        while(count<100000&&head!=null){
           head = head.next;
           count++;
        }

        return count<100000?false:true;
        
    }
}

2.快慢指针

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {


        ListNode fast = head;
        ListNode slow = head;

        while(fast!=null&&fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast==slow){
                return true;
            }
        }

        return false;
        
    }
}

3.HashSet特性

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        Set<ListNode> set = new HashSet<ListNode>();
        while(head!=null){
            if(!set.add(head)){
                return true;
            }
            head = head.next;
        }
        return false;
    }
}

160. 相交链表

在这里插入图片描述

1.经典写法

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        int countA = 0;
        int countB = 0;

        ListNode a = headA;
        ListNode b = headB;

        while(a!=null){
            countA++;
            a = a.next;
        } 

        while(b!=null){
            countB++;
            b = b.next;
        }

        int result = Math.abs(countA-countB);

        if(countA>countB){
           for(int i=0;i<result;i++){
               headA = headA.next;
           }
        }

        if(countA<countB){
           for(int i=0;i<result;i++){
               headB = headB.next;
           }
        }

        while(headA!=null&&headB!=null){
            if(headB==headA){
                return headA;
            }
            headA = headA.next;
            headB = headB.next;
        }

        return null;
    }
}

2.使用Set集合

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        Set<ListNode> set = new HashSet<ListNode>();

        while(headA!=null){
            set.add(headA);
            headA = headA.next;
        }

        while(headB!=null){
            if(set.contains(headB)){
                return headB;
            }
            headB= headB.next;
        }

        return null;
    }
}

在这里插入图片描述
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if(headA==null||headB==null){
            return null;
        }

        ListNode pA = headA;
        ListNode pB = headB;

        while(pA!=pB){
            pA = (pA == null?headB:pA.next);
            pB = (pB == null?headA:pB.next);
        }
        return pA;
    }
}

206. 反转链表

在这里插入图片描述

1.头插法

class Solution {
    public ListNode reverseList(ListNode head) {

        ListNode newhead = new ListNode(0);
        ListNode curNode = head;
        while(curNode!=null){
            ListNode temp = curNode.next;
            curNode.next = newhead.next;
            newhead.next = curNode;
            curNode = temp;

        }

        return newhead.next;


    }
}

2.迭代插入法

class Solution {
    public ListNode reverseList(ListNode head) {
        ListNode pre = null;
        ListNode cur = head; 

        while(cur!=null){
            ListNode temp = cur.next;
            cur.next = pre;
            pre =cur ;
            cur = temp;
        }
        return pre;
    }
}

234. 回文链表

在这里插入图片描述
1.传统的栈方法

import java.util.Stack;
class Solution {
   public static boolean isPalindrome(ListNode head) {

            Stack<ListNode> stack = new Stack<>();

            int totalCount = 0;
            ListNode cur = head;
            while(cur!=null){
                totalCount++;
                cur = cur.next;
            }
            if(totalCount<2){
                return true;
            }

            // 判断奇偶
            if(totalCount%2==0){
                int i = 0;
                while(head!=null){
                    if(i<(totalCount/2)){
                        stack.push(head);
                    }else{
                        ListNode temp = stack.pop();
                        if(head.val!=temp.val){
                            return false;
                        }
                    }
                    head = head.next;
                    i++;
                }

            }else if(totalCount%2==1){
                int i = 0;
                while(head!=null){
                    if(i<(totalCount/2)){
                        stack.push(head);
                    }else if(i==totalCount/2){
                        // 不用处理
                    }else{
                        ListNode temp = stack.pop();
                        if(head.val!=temp.val){
                            return false;
                        }
                    }
                    head = head.next;
                    i++;
                }
            }

            return true;

        }
}

2.精简版本的栈

import java.util.Stack;
class Solution {
   public static boolean isPalindrome(ListNode head) {

            Stack<ListNode> stack = new Stack<>();
            ListNode cur = head;
            while(cur!=null){
                stack.push(cur);
                cur = cur.next;
            }

            while(head!=null){
                if(head.val!=stack.pop().val){
                    return false;
                }
                head = head.next;
            }

            return true;
        }
}

21. 合并两个有序链表

在这里插入图片描述

  • 常规方法
/**
 * Definition for singly-linked list.
 * 
 */
class Solution {
    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
        if(list1==null){
            return list2;
        }

        if(list2==null){
            return list1;
        }

        // 比较大小
        ListNode newHead = new ListNode(0);
        ListNode curNode = newHead;

        ListNode nodeA = list1;
        ListNode nodeB = list2;
        while(nodeA!=null && nodeB!=null){
            if(nodeA.val<=nodeB.val){
                curNode.next = nodeA; 
                nodeA = nodeA.next;

            }else{
                curNode.next = nodeB;
                nodeB = nodeB.next;

            }
            curNode = curNode.next;
        }

        if(nodeA!=null){
            curNode.next = nodeA;
        }

            if(nodeB!=null){
            curNode.next = nodeB;
        }
        return newHead.next;
    }
}

2. 两数相加

在这里插入图片描述
方法一:原始方法

/**
 * 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 addTwoNumbers(ListNode l1, ListNode l2) {
        if (l1 == null) {
            return l2;
        }

        if (l2 == null) {
            return l1;
        }

        ListNode newHead = new ListNode(0);
        ListNode curNode = newHead;
        Integer add = 0;
        while (l1 != null || l2 != null) {

            Integer l1Value = 0;
            Integer l2Value = 0;

            if (l1 != null) {
                l1Value = l1.val;
            }

            if (l2 != null) {
                l2Value = l2.val;
            }

            Integer sum = l1Value + l2Value + add;
            Integer value = sum % 10;
            add = sum / 10;

            ListNode node = new ListNode(value);
            curNode.next = node;
            curNode = curNode.next;

            if (l1 != null) {
                l1 = l1.next;
            }

            if (l2 != null) {
                l2 = l2.next;
            }

        }

        if (add != 0) {
            ListNode node = new ListNode(add);
            curNode.next = node;
            curNode = curNode.next;
        }

        return newHead.next;

    }
}

方法二:递归

/**
 * 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; }
 * }
 */
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        return this.addTwoNumbers2(l1, l2, 0);
    }

    public ListNode addTwoNumbers2(ListNode l1, ListNode l2, int a) {
        if (l1 == null && l2 == null) {
            return a == 0 ? null : new ListNode(a);
        }
        if (l1 != null) {
            a += l1.val;
            l1 = l1.next;
        }
        if (l2 != null) {
            a += l2.val;
            l2 = l2.next;
        }
        return new ListNode(a % 10, addTwoNumbers2(l1, l2, a / 10));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值