博客
关于我
今天就来花时间整理一下算法吧!刚来CSDN,各位请多关照,阿里嘎多!
阅读量:780 次
发布时间:2019-03-25

本文共 8127 字,大约阅读时间需要 27 分钟。

算法,是计算机处理信息的重要方法。它是一种解决问题的思想和步骤,体现在计算机程序的设计与实现中。以下将从多个核心领域详细阐述常见算法及其实现思路。


排序算法

排序是数据处理的基础,各种排序方法各有优劣。以下是三种常见排序方法的实现逻辑:

  • 冒泡排序:每次通过比较相邻元素,完成一次交换,慢速排序。

    public static int[] BubbleSort(int[] arr) {   for (int i = 0; i < arr.length; i++) {      for (int j = 0; j < arr.length - i - 1; j++) {         if (arr[j] > arr[j + 1]) {            int temp = arr[j];            arr[j] = arr[j + 1];            arr[j + 1] = temp;         }      }   }   return arr;}
  • 选择排序:通过最小值逐步建立有序数组。

    public static int[] SelectSort(int[] arr) {   for (int i = 0; i < arr.length - 1; i++) {      for (int j = i + 1; j < arr.length; j++) {         int temp = arr[i];         if (arr[i] > arr[j]) {            arr[i] = arr[j];            arr[j] = temp;         }      }   }   return arr;}
  • 快速排序:以交换栈的中位数为枢轴,递归划分数据集。

    public int[] MySort(int[] arr) {   quicksort(arr, 0, arr.length - 1);   return arr;}public void quicksort(int[] list, int left, int right) {   if (left < right) {      int pivot = randompivot(list, left, right);      quicksort(list, left, pivot - 1);      quicksort(list, pivot + 1, right);   }}public int randompivot(int[] list, int left, int right) {   int first = list[left];   while (left < right) {      while (left < right && list[right] >= first) {         right--;      }      swap(list, left, right);      while (left < right) {         if (list[right] >= list[right - 1]) {            right--;         } else {            break;         }      }   }   return left;}

  • 堆排序

    通过模拟priority queue实现排序。堆排序的核心方法在于不断叠代地提取最大元素,最终形成有序数组。


    堆排序

    堆排序通过模拟优先队列的性质,逐步构建有序数组。其时间复杂度为O(n log n),适用于大数据量的排序场景。


    堆排序

    堆排序的实现思路是将数据按不规则插入,并通过上浮、下沉等操作维护堆的结构,最终提取有序信息。


    在继续详细探讨其余算法前,记住排序算法及其复杂度对于后续学习至关重要。接下来将深入探讨数组操作、链表结构以及二叉树遍历等问题。


    栈与队列

    栈与队列是基础数据结构,具有先进先出和先进后出的特点之一。用栈实现队列是常见的练习。


    用栈实现队列

    通过“倒置栈”结构来模拟队列的先进先出特性。

    public class Solution {    Stack stack1 = new Stack();    Stack stack2 = new Stack();    public void push(int node) {        stack1.push(node);    }    public int pop() {        if (stack2.isEmpty()) {            while (!stack1.isEmpty()) {                stack2.push(stack1.pop());            }        }        return stack2.pop();    }}

    字符串问题

    通过线性时间算法解决字符串问题后,让人惊叹技术之美。


    最长无重复子串

    用队列作为缓存,逐个字符处理,避免重复。

    public int maxLength(int[] arr) {    Queue queue = new LinkedList();    int res = 0;    for (int c : arr) {        while (queue.contains(c)) {            queue.poll();        }        queue.add(c);        res = Math.max(res, queue.size());    }    return res;}

    数组操作

    数组操作涉及数学建模,比如斐波那契数列和两数之和问题。


    斐波那契数列

    递归与非递归方法各有优劣,选择适合的实现则需要根据具体需求。

    public int Fibonacci(int n) {    if (n <= 1) return n;    return Fibonacci(n - 1) + Fibonacci(n - 2);}

    非递归实现:

    public int Fibonacci(int n) {    if (n <= 1) return n;    int first = 0, second = 1, temp;    for (int i = 2; i <= n; i++) {        temp = second;        second = first + second;        first = temp;    }    return second;}

    两数之和

    利用哈希表快速查找,时间复杂度为O(n)。

    public int[] twoSum(int[] numbers, int target) {    Map map = new HashMap();    for (int index = 0; index < numbers.length; index++) {        int cur = numbers[index];        if (map.containsKey(target - cur)) {            return new int[]{map.get(target - cur) + 1, index + 1};        }        map.put(cur, index);    }    throw new RuntimeException("results not exits");}

    链表操作

    链表常用于随机访问和多个结点操作,这些问题的解决往往别具匠心。


    链表翻转

    逐个结点逆向连接。

    public ListNode ReverseList(ListNode head) {    ListNode pre = null;    ListNode cur = head;    while (cur != null) {        pre = cur.next;        cur.next = pre;        cur = pre;    }    return pre;}

    链表环检测

    利用双指针速度差异检测环的存在。

    public class Solution {    public boolean hasCycle(ListNode head) {        if (head == null) return false;        ListNode fast = head;        ListNode slow = head;        while (fast != null && fast.next != null) {            slow = slow.next;            fast = fast.next.next;            if (fast == slow) return true;        }        return false;    }}

    链表倒数第K个节点

    分割链表后逐步追击。

    public ListNode FindKthToTail(ListNode pHead, int k) {    if (pHead == null) return pHead;    ListNode first = pHead;    while (k-- > 0) {        if (first == null) return null;        first = first.next;    }    ListNode second = pHead;    while (first != null) {        first = first.next;        second = second.next;    }    return second;}

    链表合并

    按大小顺序添加。递归法:

    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {    if (l1 == null || l2 == null) {        return l1 == null ? l2 : l1;    }    if (l1.val < l2.val) {        l1.next = mergeTwoLists(l1.next, l2);        return l1;    } else {        l2.next = mergeTwoLists(l1, l2.next);        return l2;    }}

    非递归法:

    public class Solution {    public ListNode mergeTwoLists(ListNode l1, ListNode l2) {        if (l1 == null) return l2;        if (l2 == null) return l1;        ListNode dummy = new ListNode(0);        ListNode cur = dummy;        while (l1 != null && l2 != null) {            if (l1.val > l2.val) {                cur.next = l2;                l2 = l2.next;            } else {                cur.next = l1;                l1 = l1.next;            }            cur = cur.next;        }        cur.next = l1 == null ? l2 : l1;        return dummy.next;    }}

    链表首位公共节点

    利用双指针法追踪两链表的交点。

    public class Solution {    public ListNode detectCycle(ListNode head) {        if (head == null || head.next == null) return null;        ListNode fast = head;        ListNode slow = head;        while (fast != null && fast.next != null) {            slow = slow.next;            fast = fast.next.next;            if (fast == slow) {                fast = head;                while (fast != slow) {                    slow = slow.next;                    fast = fast.next;                }                return slow;            }        }        return null;    }}

    二叉树

    关于二叉树,关键问题包括树的完整性、树的高度、层序遍历以及树的翻转操作等。


    完全二叉树判断

    通过遍历验证叶节点特性。

    public boolean isFull(TreeNode root) {    if (root == null) return false;    Queue queue = new LinkedList();    boolean isLeaf = false;    while (!queue.isEmpty()) {        TreeNode node = queue.poll();        if (isLeaf && !isLeaf(node)) {            return false;        }        if (node.left != null) {            queue.offer(node);            if (node.right != null) {                return false;            }        } else if (node.right != null) {            return false;        } else {            isLeaf = true;        }    }    return true;}

    二叉树高度计算

    递归或迭代求解树的最大高度。

    public int maxDepth(TreeNode root) {    if (root == null) return 0;    return 1 + Math.max(maxDepth(root.left), maxDepth(root.right));}

    二叉树的糖果道法列举(层序遍历)

    将树按层遍历,记录递进依据。

    public ArrayList levelOrder(TreeNode root) {    if (root == null) return new ArrayList();    ArrayList list = new ArrayList();    Queue queue = new LinkedList();    queue.offer(root);    while (!queue.isEmpty()) {        int size = queue.size();        ArrayList subList = new ArrayList();        for (int i = 0; i < size; i++) {            TreeNode node = queue.poll();            subList.add(node.val);            if (node.left != null) queue.offer(node.left);            if (node.right != null) queue.offer(node.right);        }        list.add(subList);    }    return list;}

    二叉树的糖果道法列举之之字形

    结合层数交替,形成cross_walk。

    public ArrayList zigzagLevelOrder(TreeNode root) {    if (root == null) return new ArrayList();    ArrayList list = new ArrayList();    Queue queue = new LinkedList();    queue.offer(root);    while (!queue.isEmpty()) {        ArrayList subList = new ArrayList();        for (int i = queue.size(); i > 0; i--) {            TreeNode node = queue.poll();            if ((list.size() + 1) % 2 != 0) {                subList.add(node.val);            } else {                subList.add(0, node.val);            }            if (node.left != null) queue.offer(node.left);            if (node.right != null) queue.offer(node.right);        }        list.add(subList);    }    return list;}

    二叉树内容翻转

    通过递归交换左右子节点。

    public TreeNode invertTree(TreeNode node) {    if (node == null) return null;    TreeNode temp = node.left;    node.left = node.right;    node.right = temp;    invertTree(node.left);    invertTree(node.right);    return node;}

    通过以上细节,总结技术人员解题思路和方法,这些内容涵盖了算法与数据结构的基础,希望能为你的学习提供有价值的参考。

    转载地址:http://fljuk.baihongyu.com/

    你可能感兴趣的文章
    MySQL8.0.29启动报错Different lower_case_table_names settings for server (‘0‘) and data dictionary (‘1‘)
    查看>>
    MYSQL8.0以上忘记root密码
    查看>>
    Mysql8.0以上重置初始密码的方法
    查看>>
    mysql8.0新特性-自增变量的持久化
    查看>>
    Mysql8.0注意url变更写法
    查看>>
    Mysql8.0的特性
    查看>>
    MySQL8修改密码报错ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
    查看>>
    MySQL8修改密码的方法
    查看>>
    Mysql8在Centos上安装后忘记root密码如何重新设置
    查看>>
    Mysql8在Windows上离线安装时忘记root密码
    查看>>
    MySQL8找不到my.ini配置文件以及报sql_mode=only_full_group_by解决方案
    查看>>
    mysql8的安装与卸载
    查看>>
    MySQL8,体验不一样的安装方式!
    查看>>
    MySQL: Host '127.0.0.1' is not allowed to connect to this MySQL server
    查看>>
    Mysql: 对换(替换)两条记录的同一个字段值
    查看>>
    mysql:Can‘t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock‘解决方法
    查看>>
    MYSQL:基础——3N范式的表结构设计
    查看>>
    MYSQL:基础——触发器
    查看>>
    Mysql:连接报错“closing inbound before receiving peer‘s close_notify”
    查看>>
    mysqlbinlog报错unknown variable ‘default-character-set=utf8mb4‘
    查看>>