leetcode-simple+medium-共25题-03

51. 求众数II(中等题)
ArrayList和LinkedList的区别

package com.lxh.medium;
/* 已通过(中等题) 2021.10.22 时间3ms 击败39.99% 内存42.3MB 击败43.99%
* 1.本题为每日打卡题
* 2.本题同样可以用HashMap来做
* 3.总结好ArrayList和LinkedList的联系和区别
*
* */
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class MajorityElementII0229 {
    public List<Integer> majorityElement(int[] nums) {
        Arrays.sort(nums);
        //也可以直接用ArrayList<>();
        List<Integer> mode = new LinkedList<>();
        int count = 1;
        for (int i = 0; i < nums.length-1; i++) {
            if (nums[i] == nums[i+1]) {
                count++;
            }else {
                if (count > nums.length / 3)
                    mode.add(nums[i]);
                count = 1;
            }
        }

        if (count > nums.length / 3)
            mode.add(nums[nums.length-1]);
        return mode;
    }

    public static void main(String[] args) {
        MajorityElementII0229 meii0229 = new MajorityElementII0229();
        int[] nums = {1,1,1,3,3,2,2,2};
        System.out.println(meii0229.majorityElement(nums));
    }
}

52. 错误的集合

package com.lxh.simple;
/* 已通过 2021.10.22 时间2ms 击败80.15% 内存40.4MB 击败8.83%
* Arrays.fill(count, 1);将数组count内全部赋值为1
*
* */
import java.util.Arrays;

public class SetMismatch0645 {
    public int[] findErrorNums(int[] nums) {
        /* 没有考虑到全部的可能性
        Arrays.sort(nums);
        int[] result = new int[2];
        if (nums.length == 2) {
            if (nums[0] == 1) {
                result[0] = 1;
                result[1] = 2;
                return result;
            }else {
                result[0] = 2;
                result[1] = 1;
                return result;
            }
        }
        for (int i = 1; i < nums.length ; i++) {
            if (nums[i] == nums[i-1]) {
                result[0] = nums[i];
                if (nums[i-1]-nums[i-2] != 1)
                    result[1] = nums[i] - 1;
                else
                    result[1] = nums[i] + 1;
                break;
            }
        }*/
        /* 对于1,2,2,3 这种情况无法解决。
        Arrays.sort(nums);
        int[] result = new int[2];
        int j = 1;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] - j < 0) {
                result[0] = nums[i];
                result[1] = nums[i] + 1;
                break;
            }else if (nums[i] - j > 0){
                result[0] = nums[i];
                result[1] = nums[i] - 1;
                break;
            }
        }
        return result;*/

        int[] count = new int[nums.length+1];
        int[] result = new int[2];
        //将数组全部赋值为1;
        Arrays.fill(count, 1);
        for (int i = 0; i < nums.length; i++) {
            count[nums[i]]++;
        }
        int j = 0;
        for (int i = 1; i < count.length; i++) {
            if (count[i] > 2)
               result[j++] = i;
            if (count[i] == 1)
                result[j++] = i;
            if (j >= 2)
                break;
        }
        return result;
    }

    public static void main(String[] args) {
        SetMismatch0645 sm0645 = new SetMismatch0645();
        int[] nums = {1,2,2,3};
        int[] result = sm0645.findErrorNums(nums);
        System.out.println(Arrays.toString(result));
    }
}

53. 山脉数组的封顶索引

package com.lxh.simple;
/* 已通过 2021.10.22 时间0ms 击败100% 内存38.3MB 击败96.90%
* 1.注意二分查找的变通,要学会根据具体情况来实现变通,对一些细节进行处理
*
* */
public class PeakIndexMountainArray0852 {
    public int peakIndexInMountainArray(int[] arr) {
        /*二分查找的通用型
        int left = 0;
        int right = arr.length-1;
        int middle = 0;
        while (left <= right) {
            middle = left + (right - left) / 2;
            if (arr[middle] > arr[middle-1] && arr[middle] > arr[middle+1])
                break;
            else if (arr[middle] > arr[middle-1]) {
                left = middle+1;
            }else if (arr[middle] > arr[middle+1]) {
                right = middle - 1;
            }
        }*/

        int left = 0;
        int right = arr.length-1;
        int middle = 0;
        while (left < right) {
            middle = left + (right - left) / 2;
            if (arr[middle] > arr[middle-1] && arr[middle] > arr[middle+1])
                break;
            else if (arr[middle] < arr[middle+1]) {
                left = middle;
            }else if (arr[middle] > arr[middle+1]) {
                right = middle;
            }
        }
        return middle;
    }

    public static void main(String[] args) {
        PeakIndexMountainArray0852 pima0852 = new PeakIndexMountainArray0852();
        int[] nums = {3,5,3,2,0};
        System.out.println(pima0852.peakIndexInMountainArray(nums));
    }
}

54. 交替位的二进制数

package com.lxh.simple;
/* 已通过 2021.10.25 时间0ms 击败100% 内存35MB 击败88.56%
*
*
* */

public class BinaryNumberAlternating0693 {
    public boolean hasAlternatingBits(int n) {
        while (n != 0) {
            if ((n % 2) == (n/2%2))
                return false;
            n /= 2;
        }
        return true;
    }
}

55. 数组的度

package com.lxh.simple;
/* 已通过 2021.10.25 时间46ms 击败12.36% 内存43.8MB 击败了13.26%
* 两种方案皆可
*
* */
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class DegreeAnArray0697 {
    public int findShortestSubArray(int[] nums) {
/* 方案一:用数组进行计算 对于数字范围小的本方法是可行的 因为这样可以利用数组开辟的空间和数组的小标统计出数字出现的个数并存入数组中
         但是本题数字范围为0-49999 如果用这个数组做 就得开辟一个49999大小的数组 虽然也可以做但浪费空间

        int[] array = new int[nums.length];
        int max = Integer.MIN_VALUE;
        int[] flag = new int[nums.length/2];
        Arrays.fill(flag, -1);
        int j = 0;

        // 得到每个数字出现的次数
        for (int i = 0; i < nums.length; i++) {
            array[nums[i]]++;
        }

        // 标记是哪个数字出现的次数最多或者是哪些数字出现的次数最多且一样多 存入数组flag中
        // 当max一样时接着往后面存储 但当max一旦出现更大的数时 则将前面的均变为-1;
        for (int i = 0; i < array.length; i++) {
            if (array[i] > max) {
                flag[j] = i;
                max = array[i];
                if (j > 0) {
                    flag[j--] = -1;
                }
            }else if (array[i] == max) {
                j = j + 1;
                flag[j] = i;
                max = array[i];
            }
        }

        // 根据flag数组找到对应的数字出现的初始位置和最终位置 得到子数组长度
        // 如果是出现次数的一样的 则比较谁的数组更短则取谁的长度
        j = 0;
        int result = Integer.MAX_VALUE;
        while (j < flag.length) {
            int count = 0;
            int sum = 0;
            while (j < flag.length && flag[j] == -1){
                j += 1;
            }
            if (j == flag.length)
                break;
            for (int i = 0; i < nums.length; i++) {
                if (flag[j] == nums[i]) {
                    count++;
                    sum++;
                    if (count == max) {
                        break;
                    }
                } else if (flag[j] != nums[i] && count > 0){
                    sum++;
                }
            }
            result = Math.min(result, sum);
            j++;
        }
        return result;*/

//方案二:用HashMap()来做
        if (nums.length == 1) {
            return 1;
        }

        int max = Integer.MIN_VALUE;
        int[] flag = new int[nums.length];
        Arrays.fill(flag, -1);
        int j = 0;

        Map<Integer, Integer> addup = new HashMap<>();

        for (int i = 0; i < nums.length; i++) {
            addup.put(nums[i], addup.getOrDefault(nums[i], 0) + 1);
        }

        // 标记是哪个数字出现的次数最多或者是哪些数字出现的次数最多且一样多 存入数组flag中
        // 当max一样时接着往后面存储 但当max一旦出现更大的数时 则将前面的均变为-1;
        for (Integer i : addup.keySet()) {
            if (addup.get(i) > max) {
                Arrays.fill(flag, -1);
                flag[0] = i;
                max = addup.get(i);
            }else if (addup.get(i) == max) {
                j += 1;
                flag[j] = i;
                max = addup.get(i);
            }
        }

        // 根据flag数组找到对应的数字出现的初始位置和最终位置 得到子数组长度
        // 如果是出现次数的一样的 则比较谁的数组更短则取谁的长度
        j = 0;
        int result = Integer.MAX_VALUE;
        while (j < flag.length) {
            int count = 0;
            int sum = 0;
            while (j < flag.length && flag[j] == -1){
                j += 1;
            }
            if (j == flag.length)
                break;
            for (int i = 0; i < nums.length; i++) {
                if (flag[j] == nums[i]) {
                    count++;
                    sum++;
                    if (count == max) {
                        break;
                    }
                } else if (flag[j] != nums[i] && count > 0){
                    sum++;
                }
            }
            result = Math.min(result, sum);
            j++;
        }
        return result;

    }

    public static void main(String[] args) {
        DegreeAnArray0697 daa0697 = new DegreeAnArray0697();
        int[] nums = {1, 2, 2, 3, 1};
        int[] nums1 = {1,2,2,3,1,4,2};
        int[] nums2 = {0,1};

        int[] nums4 = {47,47,72,47,72,47,79,47,12,92,13,47,47,83,33,15,18,47,47,47,47,64,47,65,47,47,47,47,70,47,47,55,47,15,60,47,47,47,47,47,46,30,58,59,47,47,47,47,47,90,64,37,20,47,100,84,47,47,47,47,47,89,47,36,47,60,47,18,47,34,47,47,47,47,47,22,47,54,30,11,47,47,86,47,55,40,49,34,19,67,16,47,36,47,41,19,80,47,47,27};
        System.out.println(daa0697.findShortestSubArray(nums4));
    }
}

56. 自除数

package com.lxh.simple;
/* 已通过 2021.10.26 时间2ms 击败66.18% 内存36.2MB 击败51.47%
*
* */
import java.util.ArrayList;
import java.util.List;

public class SelfDividingNumbers0728 {
    public List<Integer> selfDividingNumbers(int left, int right) {

        List<Integer> result = new ArrayList<>();
        while (left <=right) {
            int temp = 0;
            int flag = left;
            while (flag != 0) {
                temp = flag % 10;
                if (temp == 0) {
                    break;
                }
                if (left % temp != 0) {
                    break;
                }
                flag = flag / 10;
            }
            if (flag == 0)
                result.add(left);
            left++;
        }
        return result;
    }
}

57. 在排序数组中查找元素的第一个和最后一个位置

package com.lxh.medium;
/* 已通过 2021.10.29 时间0ms 击败100% 内存41.5MB 击败66.64% 中等题
*
*
* */
import java.util.Arrays;

public class FindFirstLast0034 {
    public int[] searchRange(int[] nums, int target) {

        int[] search = new int[2];
        Arrays.fill(search, -1);

        if (nums.length == 0) {
            return search;
        }

        int left = 0;
        int right = nums.length - 1;
        int flag = 1;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (nums[mid] == target) {
                left = mid-1;
                right = mid + 1;
                while (right < nums.length && nums[right] == nums[mid]) {
                    right++;
                }
                while (left >= 0 && nums[left] == nums[mid]) {
                    left--;
                }
                search[0] = left+1;
                search[1] = right-1;
                break;
            }else if (nums[mid] < target) {
                left = mid + 1;
            }else {
                right = mid - 1;
            }
        }
        return search;
    }
}

58. 盛最多水的容器

package com.lxh.medium;
/* 已通过 2021.10.29 时间4ms 击败了67.95% 内存49.3MB 击败88.63% 中等题
*
* */
public class ContainerWithMostWater0011 {
    public int maxArea(int[] height) {

        int maxCapacity = 0;
        int i = 0;
        int j = height.length - 1;
        while (i < j) {
            int h = Math.min(height[i], height[j]);
            maxCapacity = Math.max(maxCapacity, h * (j - i));
            if (height[i] > height[j]) {
                --j;
            }else
                ++i;
        }
        return maxCapacity;
    }
}

59. 最长回文子串

package com.lxh.medium;
/* 已通过 2021.10.30 时间24ms 击败87.21% 内存38.8MB 击败61.25%
*
*
* */
public class LongestPalindromicSubstring0005 {
    public String longestPalindrome(String s) {

        String result = "";

        for (int i = 0; i < s.length(); i++) {
        	//注意回文串可能以单个字符为中心,也可能以两个字符为中心
            result = isPalindrome(s, i, i);
            result = isPalindrome(s, i, i+1);
        }

        return result;
    }

    int maxLength = 0;
    String getStr = "";

    private String isPalindrome(String s, int start, int end) {

        while (start >= 0 && end < s.length() && s.charAt(start) == s.charAt(end)) {
            start--;
            end++;
        }
        if (end - (start + 1) > maxLength) {
            maxLength = end - (start + 1);
            //getStr = "";
            getStr = (s.substring(start+1,end));
        }
        return getStr;
    }
}

60. 只出现一次的数字III

package com.lxh.medium;
/* 已通过 2021.10.30 时间261ms 击败6.41% 内存38.6MB 击败56.22% 中等题
* 1.时间消耗太久了 再换一种方法试一试
* 2.学习ArrayList相关的知识点,怎么添加,怎么删除,怎么获取索引等。
* 3.可以利用HashSet()方法,这样就不要像ArrayList()要遍历找到对应索引再删除,HashSet()可以直接remove()
* */
import java.util.ArrayList;

public class SingleNumberIII0260 {
    public int[] singleNumber(int[] nums) {
        ArrayList<Integer> onceAppear = new ArrayList();
        int[] result = new int[2];
        for (int num : nums) {
            if (!onceAppear.contains(num)) {
                onceAppear.add(num);
            }else {
                onceAppear.remove(onceAppear.indexOf(num));
            }
        }

        int i = 0;
        for (int num : onceAppear) {
            result[i++] = num;
        }
        return result;
    }
}

61. 合并两个有序链表

package com.lxh.simple;

import com.lxh.list.ListNode;

/**
 * @Author: Tiger
 * @Description: 合并两个有序链表
 * 1. 时间0ms 击败100% 内存37.9MB 击败26.93%
 * 2. 链表 穿针法 穿针引线
 * @Date: 下午 20:38 2021/10/31 0031
 **/
public class MergeTwoSortedLists0021 {
    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
        //哨兵节点 就可以不用对头结点进行特殊处理
        ListNode dummy = new ListNode(0);
        ListNode cur = dummy;

        while (l1 != null && l2 != null) {
            if (l1.val <= l2.val) {
                cur.next = l1;
                l1 = l1.next;
            }else {
                cur.next = l2;
                l2 = l2.next;
            }
            cur = cur.next;
        }

        cur.next = l1 == null ? l2 : l1;

        return dummy.next;
    }
}

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

package com.lxh.simple;

import com.lxh.list.ListNode;

/**
 * @Author: Tiger
 * @Description: 删除排序链表中的重复元素 
 * 1.时间 0ms 击败100% 内存 37.9MB 击败60.93%
 * @Date: 下午 21:21 2021/10/31 0031
 **/
public class RemoveDuplicatesSortedList0083 {
    public ListNode deleteDuplicates(ListNode head) {
        ListNode dummy = new ListNode(-1);
        dummy.next = head;

        ListNode first = dummy, second = head;

        while (second != null) {
            while (second != null && first.val == second.val) {
                second = second.next;
            }
            if (second == null) {
                break;
            }
            first.next = second;
            first = first.next;
            second = second.next;
        }

        first.next = null;

        return dummy.next;
    }
}

63. 两数相加(链表中的两数)

package com.lxh.medium;

import com.lxh.list.ListNode;

/**
 * @Author: Tiger
 * @Description: 两数相加(链表中的两数)
 * 1. 时间2ms 击败94.80% 内存38.1MB 击败97.72%
 * @Date: 下午 16:33 2021/11/2 0002
 **/
public class AddTwoNumbersList0002 {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode sumNode = dummy;
        int carry = 0;

        while (l1 != null || l2 != null) {
            int sum = (l1 == null ? 0 : l1.val) + (l2 == null ? 0 : l2.val) + carry;
            carry = sum >= 10 ? 1 : 0;
            sum = sum >= 10 ? sum - 10 : sum;
            ListNode newNode = new ListNode(sum);

            sumNode.next = newNode;
            sumNode = sumNode.next;

            l1 = l1 == null ? null : l1.next;
            l2 = l2 == null ? null : l2.next;
        }
        if (carry > 0)
            sumNode.next = new ListNode(carry);

        return dummy.next;
    }

}

64. 两两交换链表中的节点

package com.lxh.medium;

import com.lxh.list.ListNode;

/**
 * @Author: Tiger
 * @Description: 两两交换链表中的节点
 * 1. 已通过 时间0ms 击败100% 内存36.1MB 击败28.34%
 * 2. 解法一是在不修改链表节点值的情况下解决的还有一种可以改变节点值进行操作
 * @Date: 下午 17:31 2021/11/2 0002
 **/
public class SwapNodesInPairs0024 {
    public ListNode swapPairs(ListNode head) {
        ListNode dummy = new ListNode(0);
        ListNode pre = head;
        ListNode cur = dummy;
        ListNode nex = head;
        ListNode judge = null;
        int count = 1;

        while(nex != null) {
            if (count % 2 == 0) {
                cur.next = nex;
                judge = nex.next;
                cur = nex;
                cur.next = pre;
                cur = pre;
                pre = judge;
                nex = judge;
                count++;
            }
            if (nex != null){
                nex = nex.next;
                count++;
            }
        }
        cur.next = pre;
        return dummy.next;
    }
}

65. 旋转链表

package com.lxh.medium;

import com.lxh.list.ListNode;

/**
 * @Author: Tiger
 * @Description: 旋转链表
 * 1. 时间0ms 击败100% 内存37.8MB 击败45.94% 中等题
 * 2. 找到通过旋转后头节点是哪个 断开头结点前面的节点 让前面的节点next指向null 尾结点指向head即可
 * @Date: 上午 10:28 2021/11/3 0003
 **/
public class RotateList0061 {
    public ListNode rotateRight(ListNode head, int k) {
        if (head == null || head.next == null)
            return head;

        ListNode pre = head;
        ListNode cur = null;
        ListNode nex = head;

        int count = 1;
        while(nex.next != null) {
            count++;
            nex = nex.next;
        }
        if (k == 0 || k % count == 0)
            return head;
        int lastPos = k < count ? (count - k) : (count - k % count);

        for (int i = 1; i < lastPos; i++) {
            pre =pre.next;
        }
        cur = pre.next;
        pre.next = null;
        nex.next = head;
        return cur;
    }
}

66. 反转链表II

package com.lxh.medium;

import com.lxh.list.ListNode;

/**
 * @Author: Tiger
 * @Description: 反转链表II
 * 1. 时间0ms 击败100% 内存36MB 击败43.27%
 * @Date: 下午 12:25 2021/11/3 0003
 **/
public class ReverseLinkedListII0092 {
    public ListNode reverseBetween(ListNode head, int left, int right) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;

        ListNode wholePre = dummy;
        ListNode wholeNex = null;
        ListNode cur = dummy;
        ListNode pre = null;
        ListNode nex = null;
        int count = 0;
        int flag = 1;

        //给出left前的链表节点和right后的链表节点
        while(count < right) {
            cur = cur.next;
            count++;
            if (flag == 1 && count != left) {
                wholePre = wholePre.next;
            }else if (flag == 1 && count == left){
                flag = 0;
            }
            if (count == right) {
                wholeNex = cur.next;
            }
        }

        pre = wholePre.next;
        nex = wholeNex;
        ListNode nextTem = null;

        //反转left和right之间的链表
        while(pre != wholeNex) {
            nextTem = pre.next;
            pre.next = nex;
            nex = pre;
            pre = nextTem;
        }

        wholePre.next = nex;
        return dummy.next;
    }
}

67. 奇偶链表

package com.lxh.medium;

import com.lxh.list.ListNode;

/**
 * @Author: Tiger
 * @Description: 奇偶链表
 * 1. 时间0ms 击败100% 内存38.2MB 击败16.45%
 * 2. 附:巧妙的解法
 * @Date: 下午 15:08 2021/11/3 0003
 **/
public class OddEvenLinkedList0328 {
    public ListNode oddEvenList(ListNode head) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;

        ListNode odd = dummy;
        ListNode even = null;
        ListNode temp = dummy;
        ListNode flag = null;
        int count = 0;

        //奇偶同步进行串起来
        while (temp != null) {
            temp = temp.next;
            count++;
            if (count % 2 == 1) {
                if(temp != null) {
                    odd.next = temp;
                    odd = temp;
                }
            }else {
                if (count == 2) {
                    even = temp;
                    flag = temp;
                }else {
                    even.next = temp;
                    even = temp;
                }
            }
        }
        if (flag != null)
            odd.next = flag;
        return dummy.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; }
 * }
 */
/*
class Solution {
    public ListNode oddEvenList(ListNode head) {
        if(head==null){
            return head;
        }
        ListNode evenHead=head.next;
        ListNode odd=head;
        ListNode even=head.next;
        while(even!=null&&even.next!=null){
            odd.next=even.next;
            odd=even.next;
            even.next=odd.next;
            even=odd.next;
        }
        odd.next=evenHead;
        return head;

    }
}*/

68. 两数相加II

package com.lxh.medium;

import com.lxh.list.ListNode;

/**
 * @Author: Tiger
 * @Description: 两数相加II
 * 1. 时间2ms 击败99.57% 内存38.6MB 击败68.73%
 * @Date: 下午 15:36 2021/11/3 0003
 **/
public class AddTwoNumbersII0445 {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        l1 = reverseList(l1);
        l2 = reverseList(l2);
        ListNode resultList = addNum(l1, l2);
        return reverseList(resultList);

    }

    //反转链表
    private ListNode reverseList(ListNode head) {
        ListNode cur = head;
        ListNode prev = null;
        ListNode next = null;
        while (cur != null) {
            next = cur.next;
            cur.next = prev;
            prev = cur;
            cur = next;
        }
        return prev;
    }

    //对链表的每个值进行相加并串起来
    private ListNode addNum(ListNode l1, ListNode l2) {

        ListNode newSum = new ListNode(0);
        ListNode dummy = newSum;
        int carry = 0;

        while (l1 != null || l2 != null) {
            int sum = (l1 == null ? 0 : l1.val) + (l2 == null ? 0 : l2.val) + carry;
            carry = sum >= 10 ? 1 : 0;
            sum = sum >= 10 ? sum - 10 : sum;
            ListNode newNode = new ListNode(sum);
            dummy.next = newNode;
            dummy = dummy.next;

            l1 = l1 == null ? null : l1.next;
            l2 = l2 == null ? null : l2.next;
        }
        if (carry > 0) {
            ListNode newNode = new ListNode(carry);
            dummy.next = newNode;
        }
        return newSum.next;
    }
}

69. 二进制链表转整数

package com.lxh.simple;

import com.lxh.list.ListNode;

/**
 * @Author: Tiger
 * @Description: 二进制链表转整数
 * 1. 时间0ms 击败100% 内存35.9MB 击败39.05%
 * 2. 注意对 位运算的知识重点加强
 * @Date: 下午 16:30 2021/11/3 0003
 **/
public class ConvertBinaryNumber1290 {
    public int getDecimalValue(ListNode head) {
        head = reverseList(head);
        ListNode cur = head;
        int sum = 0;
        int accu = 1;
        while (cur != null) {
            sum += cur.val * accu;
            accu *= 2;
            cur = cur.next;
        }
        return sum;
    }

    private ListNode reverseList(ListNode head) {
        ListNode cur = head;
        ListNode prev = null;
        ListNode next = null;
        while (cur != null) {
            next = cur.next;
            cur.next = prev;
            prev = cur;
            cur = next;
        }
        return prev;
    }
}

70. 合并两个链表

package com.lxh.medium;

import com.lxh.list.ListNode;

/**
 * @Author: Tiger
 * @Description: 合并两个链表
 * 1. 时间1ms 击败100% 内存42.2MB 击败64.46%
 * @Date: 下午 16:53 2021/11/3 0003
 **/
public class MergeInBetweenLinkedLists1669 {
    public ListNode mergeInBetween(ListNode list1, int a, int b, ListNode list2) {
        ListNode prev1 = null;
        ListNode next1 = null;
        ListNode cur = list1;

        for (int i = 1; i <= b; i++) {
            if (i == a) {
                prev1 = cur;
            }
            cur = cur.next;
        }
        next1 = cur.next;

        prev1.next = list2;
        prev1 = list2;

        while (prev1.next != null) {
            prev1 = prev1.next;
        }
        prev1.next = next1;
        return list1;
    }
}

71. 交换链表中的节点

package com.lxh.medium;

import com.lxh.list.ListNode;

/**
 * @Author: Tiger
 * @Description: 交换链表中的节点
 * 1. 时间2ms 击败99.70% 内存63.9MB 击败18.41%
 * @Date: 下午 17:37 2021/11/3 0003
 **/
public class SwappingNodesLinkedList1721 {
    public ListNode swapNodes(ListNode head, int k) {
        ListNode cur = head;
        ListNode first = null;
        ListNode last = head;
        int sum = 0;

        while (cur != null) {
            sum++;
            if (sum == k) {
                first = cur;
            }
            cur = cur.next;
        }

        for (int i = 1; i < sum - k + 1; i++) {
            last = last.next;
        }

        int temp = first.val;
        first.val = last.val;
        last.val = temp;
        return head;
    }
}

72. 回文链表

package com.lxh.simple;

import com.lxh.list.ListNode;

/**
 * @Author: Tiger
 * @Description: 回文链表
 * 1. 时间6ms 击败60.37% 内存48.3MB 击败69.67%
 * @Date: 下午 21:26 2021/11/3 0003
 **/
public class PalindromeLinkedList0234 {
    public boolean isPalindrome(ListNode head) {
        if (head == null || head.next ==null)
            return true;

        ListNode slow = head;
        ListNode fast = head.next;

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

        ListNode anotherHead = slow.next;
        if (fast.next != null)
            anotherHead = slow.next.next;
        slow.next = null;

        return right(anotherHead, reverseList(head));
    }

    private ListNode reverseList(ListNode head) {
        ListNode cur = head;
        ListNode prev = null;
        ListNode next = null;

        while (cur != null) {
            next = cur.next;
            cur.next = prev;
            prev = cur;
            cur = next;
        }
        return prev;
    }

    private boolean right(ListNode head1, ListNode head2) {
        while (head1 != null && head2 != null) {
            if (head1.val != head2.val)
                return false;
            head1 = head1.next;
            head2 = head2.next;
        }

        return head1 == null && head2 == null;
    }
}

73. 压缩字符串

package com.lxh.medium;

import java.util.Arrays;

/**
 * @Author: Tiger
 * @Description: 压缩字符串
 * 1. 时间1ms 击败94.46% 内存38.1MB 击败51.70%
 * @Date: 下午 17:21 2021/11/8 0008
 **/
public class StringCompression0443 {
    public int compress(char[] chars) {
        int flag = 1;
        int j = 0;
        int count = 0;
        for (int i = 0; i < chars.length - 1; i++) {
            if (chars[i] == chars[i+1]) {
                chars[j] = chars[i];
                flag++;
            }else {
                count++;
                if (flag == 1) {
                    chars[j++] = chars[i];
                }else if (flag != 1) {
                    j++;
                    String flagStr = String.valueOf(flag);
                    for (int k = 0; k < flagStr.length(); k++) {
                        chars[j++] = flagStr.charAt(k);
                    }
                    flag = 1;
                    count += flagStr.length();
                }
            }
        }
        count += 1;
        if (flag == 1) {
            chars[j] = chars[chars.length - 1];
        }else if (flag != 1){
            String flagStr = String.valueOf(flag);
            for (int k = 0; k < flagStr.length(); k++)
                chars[++j] = flagStr.charAt(k);
            count += flagStr.length();
        }

        return count;

        /* 方案二 但是消耗内存较多
        Arrays.sort(chars);
        StringBuilder result = new StringBuilder();
        int flag = 1;
        int count = 1;
        for (int i = 0; i < chars.length - 1; i++) {
            if (chars[i] == chars[i+1]) {
                flag++;
            }else {
                result.append(chars[i]);
                String flagStr = String.valueOf(flag);
                result.append(flag);
                flag = 1;
                // count += flagStr.length() + 1;
            }
        }
        result.append(chars[chars.length - 1]);
        result.append(flag);
        count = result.length();
        result.getChars(0, count, chars, 0);
        return count;*/
    }

    public static void main(String[] args) {
        StringCompression0443 sc0443 = new StringCompression0443();
        char[] chars = {'a', 'a', 'a', 'a', 'a', 'a', 'a', 'b'};
        System.out.println(sc0443.compress(chars));
    }
}

74. 棒球比赛

package com.lxh.simple;

import java.util.Stack;

/**
 * @Author: Tiger
 * @Description: 棒球比赛
 * 1. 时间2ms 击败88.59% 内存37.9MB 击败29.67%
 * @Date: 下午 16:32 2021/11/9 0009
 **/
public class BaseballGame0682 {
    public int calPoints(String[] ops) {
        Stack<Integer> stack = new Stack<>();
        stack.push(-1);
        int sum = 0;
        int beforeNum = 0;
        for (String str : ops) {
            switch (str) {
                case "C" :
                    stack.pop();
                    break;
                case "D" :
                    int getNum = stack.peek() * 2;
                    stack.push(getNum);
                    break;
                case "+" :
                    int num1 = stack.peek();
                    stack.pop();
                    int num2 = stack.peek();
                    stack.push(num1);
                    int num = num1 + num2;
                    stack.push(num);
                    break;
                default:
                    stack.push(Integer.parseInt(str));
            }
        }
        while (stack.peek() != -1) {
            sum += stack.pop();
        }
        return sum;
    }
}

75. 比较含退格的字符串

package com.lxh.simple;

import java.util.Stack;

/**
 * @Author: Tiger
 * @Description: 比较含退格的字符串
 * 1. 时间3ms 击败7.14% 内存37.1MB 击败5.06%
 * 2. 附 将StringBuilder 或者 StringBuffer 转换成 String 的写法
 * @Date: 上午 10:59 2021/11/10 0010
 **/
public class BackspaceStringCompare0844 {
    public boolean backspaceCompare(String s, String t) {
        Stack<Character> stack = new Stack<>();
        //可以不加这个哨兵 因为stack自带的判空操作 stack.isEmpty()
        stack.push('0');

        for (char ch : s.toCharArray()) {
            switch (ch) {
                case '#':
                    if (stack.peek() != '0') {
                        stack.pop();
                    }
                    break;
                default:
                    stack.push(ch);
            }
        }

        s = "";
        while (stack.peek() != '0') {
            s += stack.pop();
        }

        for (char ch : t.toCharArray()) {
            switch (ch) {
                case '#':
                    if (stack.peek() != '0') {
                        stack.pop();
                    }
                    break;
                default:
                    stack.push(ch);
            }
        }

        t = "";
        while (stack.peek() != '0') {
            t += stack.pop();
        }

        return s.equals(t);
    }
}
/*
class Solution {
    public boolean backspaceCompare(String s, String t) {
        int n1 = s.length();
        int n2 = t.length();
        StringBuffer s1 = new StringBuffer();
        StringBuffer t1 = new StringBuffer();
        for(int i=0;i<n1;i++){
            if(s.charAt(i)=='#'){
                if(s1.length()>0){
                    s1.deleteCharAt(s1.length() - 1);
                }else{
                    continue;
                }
            }else{
                s1.append(s.charAt(i));
            }
        }
        for(int i=0;i<n2;i++){
            if(t.charAt(i)=='#'){
                if(t1.length()>0){
                    t1.deleteCharAt(t1.length() - 1);
                }else{
                    continue;
                }

            }else{
                t1.append(t.charAt(i));
            }
        }

        //将StringBuilder 或者 StringBuffer 转换成String
        String s2 = s1.toString();
        String t2 = t1.toString();

        if(s2.length() !=  t2.length()){
            return false;
        }
        for(int i=0;i<s2.length();i++){
            if(s2.charAt(i) != t2.charAt(i)){
                return false;
            }
        }

        return true;

    }
}*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值