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

力扣解题汇总_JAVA

文章目录

  • 数学_简单
    • 13_罗马数字转整数
    • 66_ 加一
    • 9_回文数
    • 70_爬楼梯
    • 69_x的平方根
    • 509_斐波那契数列
    • 2235_两整数相加
    • 67_二进制求和
    • 415_字符串相加
    • 2413_最小偶倍数
    • 2469_温度转换
    • 704_二分查找(重点)
  • 数组_简单
    • 1_两数之和
    • 88_合并两个有序数组
  • 链表_简单
    • 21_合并两个有序链表
    • 203_移除链表元素
  • 字符串_简单
    • 125_验证回文串
  • 哈希表_简单
    • 169_多数元素
    • 242_有效的字母异位词
  • 双指针_简单
    • 28_找出字符串中第一个匹配项的下标
    • 344_反转字符串
  • 递归_简单
    • 206_反转链表
  • 栈_简单
    • 20_有效的括号
    • 232. 用栈实现队列
  • 队列_简单
    • 225_用队列实现栈
  • 树_简单
    • 104_二叉树的最大深度
    • 144_二叉树的前序遍历

以下汇总都是高出题频率题
按照以下顺序刷题
先简单再中等
数学 > 数组 > 链表 > 字符串 > 哈希表 > 双指针 > 递归 > 栈 > 队列 > 树
刷了多轮后再刷
图与回溯算法 >贪心 >动态规划
练熟了之后不能再开智能模式刷题了,一些细节关注不到

数学_简单

13_罗马数字转整数

class Solution {
    Map<Character, Integer> symbolValues = new HashMap<Character, Integer>() {
        {
            put('I', 1);
            put('V', 5);
            put('X', 10);
            put('L', 50);
            put('C', 100);
            put('D', 500);
            put('M', 1000);
        }
    };

    public int romanToInt(String s) {
        // I=1
        // IV=4
        // V=5
        // IX=9
        // X=10
        // XL=40
        // L=50
        // XC=90
        // C=100
        // CD=400
        // D=500
        // CM=900
        // M=1000
        int sum = 0;
        for(int i=0;i<s.length();i++){
            int value = symbolValues.get(s.charAt(i));
            //如果这个字符代表的数比后一个数大就+
            //反之则-
            if(i<s.length()-1 && value<symbolValues.get(s.charAt(i+1))){
            //这里用双&&,也保证当运行到第[s.length()-1]轮时,不执行&&后面的判断条件,就不会报错
                sum-=value;
            }
            else{
                sum+=value;
            }
        }
        return sum;
    }
}

66_ 加一

class Solution {
    public int[] plusOne(int[] digits) {
        for (int i = digits.length - 1; i >= 0; i--) {
            if (digits[i] == 9) {
                digits[i] = 0;
            } else {
                digits[i] += 1;
                return digits;
            }

        }
        //如果所有位都是进位,则长度+1
        digits= new int[digits.length + 1];
        digits[0] = 1;
        return digits;
    }
}
//千万不要想着将数组变为整数再计算,太麻烦

9_回文数

class Solution {
    //暴力解法
    public boolean isPalindrome(int x) {
        String reversedStr = (new StringBuilder(x+"")).reverse().toString();
        //StringBuilder是创建了一个StringBuilder对象,但是要转成string对象要toString()
        return (x+"").equals(reversedStr);
        //return (x+"")==reversedStr;不能这么比,因为这样比的是地址值

    }
}
class Solution {
    // 数学解法
    public boolean isPalindrome(int x) {
    	//如何是负数不可能是回文
    	//末位是0不可能是回文,除非X=0
        if (x < 0 || x % 10 == 0 && x != 0) {
            return false;
        }
        //让x代表前半段,reversex代表后半段
        //以上判断末位0正好除去了这里无法实现的翻转情况
        int reversex = 0;
        while (x > reversex) {
            reversex = reversex * 10 + x % 10;
            x = x / 10;
        }
        return reversex == x || reversex / 10 == x;
        //两种情况,位数为偶数和奇数

    }
}

70_爬楼梯

class Solution {
    public int climbStairs(int n) {
        //首先本题观察数学规律可知是斐波那契数列,但那逼公式谁记得
        //用另一种方法
        //爬到n-1层时,还有一节就到了
        //爬到n-2层时.还有两节就到了
        //所以methodNum[n]=method[n-1]+method[n-2]
        int[] methodNum = new int[n+1];
        methodNum[0] = 1;
        methodNum[1] = 1;
        for (int i = 2; i < methodNum.length; i++) {
            methodNum[i] = methodNum[i-1]+methodNum[i-2];
        }
        return methodNum[n];
    }
}

69_x的平方根

class Solution {
    public int mySqrt(int x) {
        // 非负整数
        // 二分查找,直到逼近满足k**2<=x的最大k
        int l = 0, r = x, ans = -1;
        while (l <= r) {
            int mid = (r + l) / 2;
            if ((long) mid * mid <= x) {
                ans = mid;
                l = mid + 1;
            }
            else {
                r = mid - 1;
            }
        }
        return ans;
    }
}

509_斐波那契数列

class Solution {
    public int fib(int n) {
        int[] F = new int[n+1];
        F[0] = 0;
        if(n>0){
            F[1]=1;
        }
        for (int i = 2; i < F.length; i++) {
            F[i] = F[i-1]+F[i-2];
        }
        return F[n];

    }
}

2235_两整数相加

class Solution {
    public int sum(int num1, int num2) {
        return num1+num2;
    }
}

67_二进制求和

class Solution {
    public String addBinary(String a, String b) {
        //StringBuffer是可变的字符串类,String 是不可变的对象
        StringBuffer ans = new StringBuffer();

        //取两个字符串中最大长度的字符串的长度
        //carry为计算记录,可算出当前位值和进位值
        int n = Math.max(a.length(), b.length()), carry = 0;
        for (int i = 0; i < n; ++i) {
            //比如'1'-'0',两个字符串相减就是ascii码整数差值
            //从末尾位向前计算
            //当超过较短字符串长度的位计算,补零计算
            carry += i < a.length() ? (a.charAt(a.length() - 1 - i) - '0') : 0;
            carry += i < b.length() ? (b.charAt(b.length() - 1 - i) - '0') : 0;
            //添加本位的计算结果
            ans.append((char) (carry % 2 + '0'));
            //记录进位值,可能为0,可能为1
            carry /= 2;
        }

        //最后的进位还是1,再进位
        if (carry > 0) {
            ans.append('1');
        }
        //翻转过来,因为计算是先低位再高位,但是显示应该是先高位再低位
        ans.reverse();
        //返回值要返回字符串类型
        return ans.toString();
    }
}

415_字符串相加

//思路与二进制求和相同
class Solution {
    public String addStrings(String num1, String num2) {
        StringBuffer ans = new StringBuffer();
        int carry = 0;
        int maxLen = Math.max(num1.length(),num2.length());
        for (int i = 0; i < maxLen; i++) {
            carry+=i<num1.length() ? num1.charAt(num1.length()-1-i)-'0':0;
            carry+=i<num2.length() ? num2.charAt(num2.length()-1-i)-'0':0;
            ans.append(carry%10);
            carry /=10;
        }
        if(carry!=0){
            ans.append(carry);
        }
        ans.reverse();
        return ans.toString();

    }
}

2413_最小偶倍数

class Solution {
    public int smallestEvenMultiple(int n) {
        if(n%2==0){
            return n;
        }
        else{
            return 2*n;
        }
    }
}

2469_温度转换

class Solution {
    public double[] convertTemperature(double celsius) {
        double[] ans = new double[2];
        ans[0] = celsius+273.15;
        ans[1] = celsius*1.80+32.00;
        return ans;

    }
}

704_二分查找(重点)

class Solution {
    public int search(int[] nums, int target) {
        Integer l = 0;
        Integer r = nums.length-1;
        while(l<=r){
            Integer mid = (l+r)/2;
            if(nums[(l+r)/2]>target){
                //新的右边界一定要是mid-1
                //边界的更新一定要精确,需要思考最后的极端情况
                //如果不精确,最后就无法收敛到目标值
                //或者无法因为数组中不包含目标值,而不能跳出l<=r的满足条件,不精确将一直满足l<=r
                r = mid-1;
            }
            else if(nums[(l+r)/2]<target){
                //新的左边界一定要是mid+1
                l = mid+1;
            }
            else{
                return mid;
            }
        }
        return -1;
    }
}

数组_简单

1_两数之和

class Solution {
    public int[] twoSum(int[] nums, int target) {
        //建立一个哈希表,存放数值(key)和下标(value)
        //使用Map接口作为类型相比使用HashMap更加灵活
        Map<Integer,Integer> hashtable = new HashMap<Integer,Integer>();
        for (int i = 0; i < nums.length; i++) {
            //每次与哈希中比对,保证不重复利用一个数值,因为此数值还没存放到表中
            if(hashtable.containsKey(target-nums[i])){
                return new int[]{hashtable.get(target-nums[i]),i};
            }
            //没有满足的配对,再将此值放入哈希表中
            hashtable.put(nums[i], i);
        }
        return null;

    }
}

88_合并两个有序数组

class Solution {
    public void merge(int[] nums1, int m, int[] nums2, int n) {
        //逆双指针
        int p1 = m-1,p2 = n-1; 
        for (int i = 0; i < nums1.length; i++) {
            //从后面向nums1中插入值,不会覆盖nums1含值的位置
            if(p1>=0&&p2>=0){
                if(nums1[p1]>nums2[p2]){
                    //nums1的含值尾值大,插入num1的尾部
                    nums1[nums1.length-1-i] =  nums1[p1--];
                }
                else{
                    //nums2的含值尾值大,插入num1的尾部
                    nums1[nums1.length-1-i] = nums2[p2--];
                }
            }
            else if(p1<0){
                nums1[nums1.length-1-i] = nums2[p2--];
            }
            else if(p1>0){
                nums1[nums1.length-1-i] = nums1[p1--];
            }
        }
        return;
    }
}

链表_简单

21_合并两个有序链表

/**
 * 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 prehead = new ListNode(-1);
        ListNode prev = prehead;
        //此时 prehead和prev只是同一个节点的不同声明,不要将prehead和prev当作两个节点
        while(list1 !=null && list2!=null){
            if(list1.val <= list2.val){
                prev.next=list1;
                list1 = list1.next;
            }
            else{
                prev.next = list2;
                list2 = list2.next;
            }
            prev = prev.next;
        }
        prev.next = list1 == null?list2:list1;
        return prehead.next;
    }
}

203_移除链表元素

/**
 * 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 newhead = head;
        ListNode ptr = newhead;
        while (ptr!=null) {
            if(newhead.val == val && ptr == newhead){
                //这是我自己的解法,但是其实官方迭代的思路是在head节点之前
                //链接一个newhead.next = head,就简单多了,不用嵌套的逻辑了
                newhead = newhead.next;
                ptr = newhead;
            }
            else{
                while(ptr.next !=null && ptr.next.val == val){
                    ptr.next = ptr.next.next;
                }
                ptr = ptr.next;
            }
        }
        return newhead;
    }
}

字符串_简单

125_验证回文串

解1

class Solution {
    public boolean isPalindrome(String s) {
        //先去除除了字母和数字的特殊字符.放入sgood
        //将sgood和sgood.reverse对比,相等则回文
       StringBuffer sgood = new StringBuffer();
       int length = s.length();
        for (int i = 0; i < length; i++) {
            char ch = s.charAt(i);
            if(Character.isLetterOrDigit(ch)){
                sgood.append(Character.toLowerCase(ch));
            }
        }
       StringBuffer reverse = new StringBuffer(sgood).reverse();
       return sgood.toString().equals(reverse.toString());
    }
}

解2

class Solution {
    public boolean isPalindrome(String s) {
        //在原字符串上比对
        //Time O(n),space O(1)
        int l = 0;
        int r = s.length()-1;
        while(l<r){
            while(l<r && !Character.isLetterOrDigit(s.charAt(l))){
                l++;
            }
            while(l<r && !Character.isLetterOrDigit(s.charAt(r))){
                r--;
            }
                if(l<r&&Character.toLowerCase(s.charAt(l))!=Character.toLowerCase(s.charAt(r)))
            {
                return false;
            }
            l++;
            r--;
        }
        return true;
    }
}

哈希表_简单

哈希表的作用

  • 统计一系列成员的数量

169_多数元素

import java.util.Map.Entry;
class Solution {
    public int majorityElement(int[] nums) {
        //集合只支持放引用数据类型
        HashMap<Integer,Integer> hashMap = new HashMap<>();
        for (Integer i = 0; i < nums.length; i++) {
            Integer num = nums[i];
            if(!hashMap.containsKey(num)){
                hashMap.put(num, 1);
            }
            else{
                Integer count = hashMap.get(num);
                count++;
                hashMap.put(num, count);
            }
        }
        Integer maxCount = 0;
        Integer maxValue = null;
        for (Entry<Integer,Integer> entrySet : hashMap.entrySet()) {
            if(maxCount < entrySet.getValue()){
                maxCount = entrySet.getValue();
                maxValue = entrySet.getKey();
            }
        }
        return maxValue;
    }
}

242_有效的字母异位词

class Solution {
    public boolean isAnagram(String s, String t) {
        HashMap<Character,Integer> sHashMap = new HashMap<>();
        HashMap<Character,Integer> tHashMap = new HashMap<>();
        Character sCh;
        Character tCh;
        //我这里理解起来比较容易
        //官方只用了一个hashmap,比较优雅
        //注意,HashMap的泛型是Character也不严谨,并不完全适用于unicode
        //Character只存占两字节的字符,而unicode有超过100000个不同的字符
        //远超65535个,官方也是Character,我觉得也不严谨
        //所以最正确的方法应该是先强转成Integer型(4字节)再存入hashmap
        if(s.length()!=t.length()){
            return false;
        }
        for (int i = 0; i < s.length(); i++) {
            sCh = s.charAt(i);
            if(!sHashMap.containsKey(sCh)){
                sHashMap.put(sCh, 1);
            }
            else{
                Integer count = sHashMap.get(sCh);
                sHashMap.put(sCh, count+1);
            }
            tCh = t.charAt(i);
            if(!tHashMap.containsKey(tCh)){
                tHashMap.put(tCh, 1);
            }
            else{
                Integer count = tHashMap.get(tCh);
                tHashMap.put(tCh, count+1);
            }
        }
        return sHashMap.equals(tHashMap);
    }
}

双指针_简单

28_找出字符串中第一个匹配项的下标

class Solution {
    public int strStr(String haystack, String needle) {
        //双指针
        //一个指针用来匹配
        //另一个指针如果在另一个指针匹配时,留在疑似匹配串的头部
        Integer head = 0;
        for (Integer idx = 0; idx < haystack.length(); ) {
            if(haystack.charAt(idx)==needle.charAt(idx-head)){
                if(idx-head+1 ==needle.length()){
                    return head;
                }
                idx++;
            }
            else{
                head++;
                idx = head;
            }
        }
        return -1;
    }
}

344_反转字符串

class Solution {
    public void reverseString(char[] s) {
        Integer len= s.length;
        Integer i = 0;
        //意识不到数组的最后一个元素的索引是len-1也是老毛病了
        while(i<=(len/2-1)){
            Character temp = s[i];
            s[i] = s[len-1-i];
            s[len-1-i]=temp;
            i++;
        }
    }
}

递归_简单

206_反转链表

/**
 * 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 reverseList(ListNode head) {
        //递归思想
        //先用递归方法之前的程序,递归到最后一层(最后一个节点)
        //再用递归方法之后的程序翻转指针

        //为什么要加head==null的判断条件,
        //为什么head==null在前,head.next==null在后
        //因为如果链表为[],直接报错,触发空指针异常
        if(head==null||head.next==null){
            return head;
        }
        ListNode newHead = reverseList(head.next);
        head.next.next = head;
        head.next = null;//递归到最后一层的时候防止1<->2互相指,1<->2<-3<-4<-5
        return newHead; 
    }
}

栈_简单

20_有效的括号

class Solution {
    public boolean isValid(String s) {
        //栈思想
        //栈的接口
        //Deque是双端队列,是接口,此接口实现了queue队列
        //LinkedList实现了deque双端队列接口
        //deque双端队列可以作为栈(push()/pop())或队列(offer()/poll())使用
        //pop(),从栈顶移除一个元素
        //peek(),查看栈顶元素
        //push(),放入栈顶
        //push和pop都是在队头添加和删除
        Deque<Character> deque = new LinkedList<>();
        //Deque为队列,可以作为栈使用
        for (int i = 0; i < s.length(); i++) {
            Character ch = s.charAt(i);
            //有左括号就在栈中放入对应的右括号
            if(ch == '('){
                deque.push(')');
            }
            else if (ch == '[') {
                deque.push(']');
            }
            else if (ch == '{') {
                deque.push('}');
            }
            //没循环完,且左括号就遍历完,就为空说明有余下的右括号
            //匹配不上也false
            else if(deque.isEmpty()||deque.peek()!=ch){
                return false;
            }
            else{
                deque.pop();
            }
        }
        // 完美匹配上,栈应该为空
        return deque.isEmpty();
    }
}

232. 用栈实现队列

class MyQueue {

    Deque<Integer> inStack;
    Deque<Integer> outStack;
    //两个栈,一个作为入队列,一个作为出队列
    public MyQueue() {
        inStack = new LinkedList<>();
        outStack = new LinkedList<>();
    }
    
    public void push(int x) {
        inStack.push(x);
    }
    
    public int pop() {
        //在出队列的时候才将inStack的数据移到outStack,如果在入队列的时候,每一次移动时间复杂度都将是O(n)
        //只有outStack为空,才能将inStack移到outStack,不然inStack的新数据将把outStack中的旧数据压到栈底
        while(outStack.isEmpty()){
            //移动直到inStack为空
            while(!inStack.isEmpty()){
                outStack.push(inStack.pop());
            }
        }
        return outStack.pop();

    }
    
    public int peek() {
        //与pop()操作同理
        while(outStack.isEmpty()){
            while(!inStack.isEmpty()){
                outStack.push(inStack.pop());
            }
        }
        return outStack.peek();
    }
    
    public boolean empty() {
        if(inStack.isEmpty() && outStack.isEmpty()){
            return true;
        }
        return false;
    }
}

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = new MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();
 * boolean param_4 = obj.empty();
 */

队列_简单

225_用队列实现栈

class MyStack {
    //LinkedList是类,LinkedList中实现了deque接口
    //Queue队列是一个接口,deque双端队列中实现了queue接口
    Queue<Integer> queue1;
    Queue<Integer> queue2;
    public MyStack() {
        queue1 = new LinkedList<Integer>();
        queue2 = new LinkedList<Integer>();
    }
    
    public void push(int x) {
        queue2.offer(x);
        while(!queue1.isEmpty()){
            queue2.offer(queue1.poll());
        }
        Queue<Integer> temp = queue1;
        queue1 = queue2;
        queue2 = temp;
    }
    
    public int pop() {
        return queue1.poll();
    }
    
    public int top() {
        return queue1.peek();
    }
    
    public boolean empty() {
        return queue1.isEmpty();
    }
}

/**
 * Your MyStack object will be instantiated and called as such:
 * MyStack obj = new MyStack();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.top();
 * boolean param_4 = obj.empty();
 */

树_简单

104_二叉树的最大深度

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public int maxDepth(TreeNode root) {
        //递归思想
        if(root == null){
            return 0;
        }
        else{
            int lDepth = maxDepth(root.left);
            int rDepth = maxDepth(root.right);
            return Math.max(lDepth,rDepth) + 1;
        }
    }
}

144_二叉树的前序遍历

import com.sun.source.tree.Tree;

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        if(root != null){
            list.add(root.val);
            if(root.left != null){
                List<Integer> left = preorderTraversal(root.left);
                list.addAll(left);
        }

            if(root.right != null){
                List<Integer> right = preorderTraversal(root.right);
                list.addAll(right);
            }
        }
        return list;
    }
}

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

相关文章:

  • Spring Boot经典面试题及答案
  • Oracle 批量投入数据方法总结
  • 港科夜闻 | 香港科大与微软亚洲研究院签署战略合作备忘录,推动医学健康教育及科研协作...
  • 【C语言】_求字符串长度函数strlen
  • MySQL-索引
  • Redis--21--大Key问题解决方案
  • 仿射密码实验——Python实现(完整解析版)
  • 大模型——RAG
  • 设置完端口转发后,本机可以ping通公网设备,但公网设备无法ping通本机内网ip
  • RabbitMQ与Kafka的比较及应用
  • CSS布局与响应式
  • G1原理—G1的GC日志分析解读
  • 二百八十四、Flink——Flink提交任务两种方式(亲测、附截图)
  • 去中心化身份验证:Web3如何确保元宇宙中的身份安全
  • 如何在gitlab cicd中实现每月10号上午执行
  • 我的世界-与门、或门、非门等基本门电路实现
  • 70_Redis数据结构-RedisObject
  • 有效提取激光雷达点云平面点
  • 字符串dp系列
  • SC34018 免提手柄式扬声电话系统
  • 生产管理看板助力节能科技公司实现数据自动化管理
  • PostMan测试webSocket接口(保姆级教程)
  • 浅谈云计算16 | 存储虚拟化技术
  • 力扣第 54 题: 螺旋矩阵
  • Js:正则表达式及其方法
  • 基于单片机的语音控制玩具汽车的设计