leetcode java数据结构算法整理(更新中)

目录

github地址

1.链表反转

2.快速排序

3.归并排序

4.两数之和

5.两数相加

6.无重复字符的最长子串

7.三个数的乘积

8.二叉树的最小高度--->深度优先(栈)

递归没看懂的可以留言。

9.二叉树的最小高度--->广度优先算法(队列)

10.最长连续递增数列-->贪心算法

11.最长的回文子字符串


github地址

1.链表反转

2.快速排序

    public static int[] quickSortFun(int[] arr, int low, int high) {

        if (low < high) {
            int mid = qSort(arr, low, high);
            quickSortFun(arr, low, mid - 1);
            quickSortFun(arr, mid + 1, high);
        }
        return arr;
    }

    private static int qSort(int[] arr, int low, int high) {
        int prviod = arr[high];
        int i = low - 1;
        int j = high;
        while (i < j) {
            while (arr[++i] < prviod && i < j) ;
            arr[j] = arr[i];
            while (arr[--j] > prviod && i < j) ;arr[i] = arr[j];

        }
        arr[i] = prviod;
        return i;
    }

执行顺序:

原数组:1,2,5,3,4,7,0

(1)以0作为基准数
       0,(2,5,3,4,7,1)
(2)以1为基准数
      0,1,(5,3,4,7,2)
(3)以2为基准数
      0,1,2,(3,4,7,5)
(4)以5为基准数
      0,1,2,(3,4)5,(7)
(5)以4为基准数,以7为基准数
     0,1,2,3,4,5,7

3.归并排序

 public static void main(String[] args) {

        int[] arr = {2, 1, 5, 3, 9, 4, 0};
        System.out.println("初始数组:" + Arrays.toString(arr));

        mergeSort1(arr, 0, arr.length - 1);

        System.out.println("排序后数组:" + Arrays.toString(arr));
    }

    private static void mergeSort1(int[] arr, int low, int high) {

        if (low >= high) return;
        int mid = (high + low) / 2;
        mergeSort1(arr, low, mid);
        mergeSort1(arr, mid + 1, high);
        merge(arr, low, mid, high);

    }

    private static void merge(int[] arr, int low, int mid, int high) {

        int[] ret = new int[high - low + 1];
        int s1 = low;
        int s2 = mid + 1;
        int index = 0;
        
        while (s1 <= mid && s2 <= high) ret[index++] = arr[s1] < arr[s2] ? arr[s1++] : arr[s2++];
        while (s2 <= high) ret[index++] = arr[s2++];
        while (s1 <= mid) ret[index++] = arr[s1++];
        for (int j = 0; j < ret.length; j++) arr[j + low] = ret[j];

    }

 

初始数组:[2, 1, 5, 3, 9, 4, 0]
排序后数组:[0, 1, 2, 3, 4, 5, 9]

4.两数之和

public class LeetCode1_twoSum {

    /**
     * 解体思路:
     * 1.创建一个map
     * 2.for循环遍历nums数组
     * 3.用target减去nums[i]
     * 以计算那个数能根当前的数字相加得到target
     * 4.检查map里面有没有这个数,
     * 如果有则返回结果
     * 如果没有则把nums[i]当作key
     * i作为value放入map中
     */
    public static void main(String[] args) {

        int[] nums = {2, 3, 11, 7};
        Map<Integer, Integer> map = new HashMap<>();

        int target = 9;

        for (int i = 0; i < nums.length; i++) {
            if (!map.containsKey(target - nums[i])) {
                map.put(nums[i], i);
            } else {
                System.out.println("第" + map.get(target - nums[i]) + "个数,即" + (target - nums[i]) + "和" + nums[i] + "的结果是" + target);
            }
        }

    }
}
第0个数,即2和7的结果是9

5.两数相加

/**
 * @Title: LinkedNode
 * @Description: 链表节点类
 */
public class LinkedNode {

    public int data;
    public LinkedNode next;

    //实例化
    public LinkedNode(int data) {
        this.data = data;
    }

    @Override
    public String toString() {
        return "LinkedNode{" +
                "data=" + data +
                ", next=" + next +
                '}';
    }
}

/**
 * @Title: SingleLinkedList
 * @Description: 实例化链表
 */
public class SingleLinkedList {

    private LinkedNode head = new LinkedNode(0);

    //头节点
    public LinkedNode getHead() {
        return head;
    }

    //添加节点
    public void addLinkedNode(LinkedNode node) {
        //因为head节点是不能动得,因此我们需要一个辅助节点 temp来遍历
        LinkedNode temp = head;
        while (temp.next != null) {
            temp = temp.next;
        }
        temp.next = node;
    }

    //显示列表
    public void showLinkedList(LinkedNode head) {
        if (head.next == null) {
            System.out.println("链表为空");
            return;
        }
        //因为头节点不能动,所以需要辅助变量来遍历
        LinkedNode temp = head.next;
        if (temp == null) {
            System.out.println("空链表");
            return;
        }
        ArrayList<Integer> integers = new ArrayList<>();
        while (temp != null) {
            integers.add(temp.data);
            temp = temp.next;
        }
        //逆序输出
        for (int i = integers.size() - 1; i >= 0; i--) {
            System.out.print(integers.get(i));
        }


    }

    //修改链表节点数据
    public void updateLinkedList(LinkedNode node) {
        if (head.next == null) {
            System.out.println("空链表");
            return;
        }

        LinkedNode temp = head.next;
        boolean flag = false;

        while (true) {
            if (temp.next == null) break;
            if (temp.data == node.data) {
                flag = true;
                break;
            }
            temp = temp.next;
        }
        if (flag) {
            temp.data = node.data;
        } else {
            System.out.println("没有找到该" + node.data);
        }
    }



}
public class LeetCode2_AddTwoNumbers {

    /**
     * 给出两个非空的链表用来表示两个非负的整数,其中他们各自的位数是按照逆序的方式存储,并且它们的每个节点只能存储一位数字
     * 如果我们将这两个数相加起来,则会返回一个新的链表来表示他们的和
     * 例如:(2->4->3)+(5->6->7->1)=(7->0->1->2)
     * 原因:342+465=807
     */
    public static void main(String[] args) {

        /**
         * 初始化两个链表
         */
        SingleLinkedList l1 = new SingleLinkedList();

        l1.addLinkedNode(new LinkedNode(8));


        SingleLinkedList l2 = new SingleLinkedList();

        l2.addLinkedNode(new LinkedNode(2));
        l2.addLinkedNode(new LinkedNode(0));
        l2.addLinkedNode(new LinkedNode(1));


        /**
         * 结果写入到新的链表
         */
        SingleLinkedList dummy = new SingleLinkedList();
        LinkedNode curr = dummy.getHead();

        LinkedNode node1 = l1.getHead().next;
        LinkedNode node2 = l2.getHead().next;


        int carry = 0;
        while (node1 != null || node2 != null) {
            int sum = 0;
            if (node1 != null) {
                sum += node1.data;
                node1 = node1.next;
            }
            if (node2 != null) {
                sum += node2.data;
                node2 = node2.next;
            }
            sum += carry;
            LinkedNode node = new LinkedNode(sum % 10);

            curr.next = node;
            carry = sum / 10;
            curr = curr.next;

        }

        if(carry>0){
            curr.next=new LinkedNode(carry);
        }
        dummy.showLinkedList(dummy.getHead());


    }


}

结果展示:


110
Process finished with exit code 0

6.无重复字符的最长子串

/**
 * @Title: LeetCode3_LongestSubstringWithoutRepeatingCharacters
 * @Description: 无重复字符的最长子串--->滑动窗口

 */
public class LeetCode3_LongestSubstringWithoutRepeatingCharacters {
    public static void main(String[] args) {
        String word = "abcabcdb";
        char[] chars = word.toCharArray();
        List<Character> list = new ArrayList<>();

        int maxLength = 0, j = 0;

        for (int i = 0; i < chars.length; i++) {
            if (!list.contains(chars[i])) {
                list.add(chars[i]);
                maxLength = Math.max(maxLength, list.size());
            } else {
                while (list.contains(chars[i])) {

                    list.remove(new Character(chars[j]));
                    j++;
                }
                list.add(chars[i]);
            }


        }


        System.out.println(maxLength);
    }

}

输出结果:

4

Process finished with exit code 0

7.三个数的乘积

/**
 * @Title: LeetCode4_ThreeNumberMultiply
 * @Description: 三个数的乘积:整型数组nums,在数组中找出三个数组组成的最大乘积,并输出这个乘积
 * 1.数组中全部为正数,选出最大的三个正数
 * 2.数组中全部为负数,选出最大的三个负数
 * 3.数组中有正有负,选出两个最小的负数乘上最大的正数,如果只有一个负数就回到 1 的情况中了
 * <p>
 * 综上所属:就只需要考虑两种情况(1)找出三个最大的数,求乘积
 * (2)找出两个最小的数和一个最大的数,求乘积
 * 判断上面两种情况那个结果最大
 */
public class LeetCode4_ThreeNumberMultiply {

    public static void main(String[] args) {

        int[] nums = {-1, -2, 3, 4, 6, -7};

        System.out.println(sort(nums));
        System.out.println(getMaxMin(nums));


    }

    //解法1:先进行排序找出最大的数
    public static int sort(int[] nums) {
        Arrays.sort(nums);//内部使用的是快排,时间复杂度是  NlogN
        int n = nums.length;

        return Math.max(nums[0] * nums[1] * nums[n - 1], nums[n - 1] * nums[n - 2] * nums[n - 3]);
    }

    //解法2:线性扫描
    public static int getMaxMin(int[] nums) {
        int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
        int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE;

        for (int x : nums) {
            //找出最小的两个数
            if (x < min1) {
                min2 = min1;
                min1 = x;
            } else if (x < min2) {
                min2 = x;
            }

            //找出最大的三个数
            if (x > max1) {
                max3 = max2;
                max2 = max1;
                max1 = x;
            } else if (x > max2) {
                max3 = max2;
                max2 = x;
            } else if (x > max3) {
                max3 = x;
            }

        }

        return Math.max(min1 * min2 * max1, max1 * max2 * max3);
    }
}

结果展示:

84
84

Process finished with exit code 0

8.二叉树的最小高度--->深度优先(栈)


/**
 * @Title: LeetCode6_LongestPalidromicSubstring
 * @Description: 二叉树的最小深度:深度优先算法
 * 二叉树逻辑结构:
 *          1
 *      2      3
 *   4   5   6
 *          7
 */
public class LeetCode6_BiTreeMinDepth {

    public static void main(String[] args) {
        //构建一颗二叉树
        TreeNode node7 = new TreeNode(7, null, null);
        TreeNode node6 = new TreeNode(6, node7, null);
        TreeNode node5 = new TreeNode(5, null, null);
        TreeNode node4 = new TreeNode(4, null, null);
        TreeNode node3 = new TreeNode(3, node6, null);
        TreeNode node2 = new TreeNode(2, node4, node5);
        TreeNode node1 = new TreeNode(1, node2, node3);

        System.out.println(minDepth(node1));

    }

    public static int minDepth(TreeNode root) {
        //首先判断树是否为空
        if (root == null) {
            System.out.println("二叉树为空");
            return 0;
        }

        //此为叶子节点
        if (root.left == null && root.right == null) {
            return 1;
        }
        int min = Integer.MAX_VALUE;
        if (root.left != null) {
            min = Math.min(minDepth(root.left), min);
        }
        if (root.right != null) {
            min = Math.min(minDepth(root.right), min);
        }
        return min + 1;
    }

    //二叉树的静态内部类
    static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }

}

递归没看懂的可以留言。

9.二叉树的最小高度--->广度优先算法(队列)


/**
 * @Title: LeetCode7_BiTreeMinDepthBreadth
 * @Description: 二叉树的最小深度:广度优先  时间复杂度:O(n)  空间复杂度:O(n)
 * 二叉树逻辑结构:
 *          1
 *      2      3
 *   4   5   6
 *          7
 */
public class LeetCode7_BiTreeMinDepthBreadth {
    public static void main(String[] args) {
        //构建一颗二叉树
        TreeNode node7 = new TreeNode(7, null, null);
        TreeNode node6 = new TreeNode(6, node7, null);
        TreeNode node5 = new TreeNode(5, null, null);
        TreeNode node4 = new TreeNode(4, null, null);
        TreeNode node3 = new TreeNode(3, node6, null);
        TreeNode node2 = new TreeNode(2, node4, node5);
        TreeNode node1 = new TreeNode(1, node2, node3);

        System.out.println(minDepth(node1));
    }

    public static int minDepth(TreeNode root) {

        if (root == null) {
            return 0;
        }
        Queue<TreeNode> queue = new LinkedList();
        root.deep = 1;
        queue.offer(root);

        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();
            if (node.left == null && node.right == null) {
                return node.deep;
            }
            if (node.left != null) {
                node.left.deep = node.deep + 1;
                queue.offer(node.left);
            }

            if (node.right != null) {
                node.right.deep = node.deep + 1;
                queue.offer(node.right);
            }
        }
        return 0;
    }

    //二叉树的静态内部类
    static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        int deep;

        TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }
}

10.最长连续递增数列-->贪心算法


/**
 * @Title: LeetCode8_LongestContinuousIncreasingSequence
 * @Description: 给定一个未经排序的整数数组,找到最长且连续递增的子序列,并返回其长度--->贪心算法
 * 从数组的下标为0的位置开始,
 * 依次往后数当后一个数(i)大于等于前一个数(j)的时候将开始位置变为i,
 * 将走过的长度记录到max中
 * 最后返回max
 */
public class LeetCode8_LongestContinuousIncreasingSequence {

    public static void main(String[] args) {
        int length = findLength(new int[]{1, 2, 3, 2, 3, 4, 3, 4, 5, 6});
        System.out.println(length);
    }

    private static int findLength(int[] ints) {

        int start = 0, max = 0;

        for (int i = 1; i < ints.length; i++) {
            if (ints[i] <= ints[i - 1]) {
                start = i;
            }
            max = Math.max(max, i - start + 1);
        }

        return max;
    }

}

11.最长的回文子字符串


/**
 * @Title: LeetCode5_LongestPalidromicSubstring
 * @Description: 最长的回文子字符串
 * 解题思路:
 * 1.如果字符串长度小于2,直接返回源字符串
 * 2.定义两个变量,一个start存储当前找到的最大回文字符串的起始位置,另一个maxLength记录字符串的长度(终止位置就是start+maxLength)
 * 3.创建一个helper function,判断左边和右边是否越界,同时最左边的字符是否等于最右边的字符。
 * 如果以上三个条件都满足,则判断是否需要更新回文字符串的最大长度及最大字符串的起始位置。然后将left--,right++继续判断,直到不满足三个条件为止
 * 4.遍历字符串,每个位置调用helper function 两遍,第一遍检查i-1,i+1,第二遍检查i ,i+1
 *
 * 时间复杂度为O(n^2)
 */
public class LeetCode5_LongestPalidromicSubstring {

    public static void main(String[] args) {

        System.out.println(getPalidromicSubstring("abcbc"));

    }

    public static String getPalidromicSubstring(String str) {

        if (str.length() < 2) {
            return str;
        }
        int start = 0;
        int maxLength = 1;


        for (int i = 0; i < str.length(); i++) {

            int left = i;
            int right = i + 1;
            while (left >= 0 && right < str.length() && str.charAt(left) == str.charAt(right)) {

                if (right - left + 1 > maxLength) {
                    maxLength = right - left + 1;
                    start = left;
                }
                left--;
                right++;
            }
        }

        for (int i = 0; i < str.length(); i++) {
            int left = i - 1;
            int right = i + 1;
            while (left >= 0 && right < str.length() && str.charAt(left) == str.charAt(right)) {

                if (right - left + 1 > maxLength) {
                    maxLength = right - left + 1;
                    start = left;
                }
                left--;
                right++;
            }
        }
        return str.substring(start, start + maxLength);
    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值