一些算法(基于Java)

  1. 两数之和(Two Sum)

    • 目标:在数组中找到两个数,使它们的和等于给定的目标值。
    • 解题思路:使用哈希表(HashMap)来存储每个元素及其索引,遍历数组,查找是否存在与当前元素的差等于目标值的另一个元素。
    • 代码示例:
      public int[] twoSum(int[] nums, int target) {
          Map<Integer, Integer> map = new HashMap<>();
          for (int i = 0; i < nums.length; i++) {
              int complement = target - nums[i];
              if (map.containsKey(complement)) {
                  return new int[]{map.get(complement), i};
              }
              map.put(nums[i], i);
          }
          throw new IllegalArgumentException("No two sum solution");
      }
      
  2. 反转链表(Reverse Linked List)

    • 目标:将链表反转,即将链表的指针方向反转。
    • 解题思路:使用三个指针,分别指向当前节点、前一个节点和后一个节点,迭代遍历链表进行指针反转。
    • 代码示例:
      public ListNode reverseList(ListNode head) {
          ListNode prev = null;
          ListNode current = head;
          while (current != null) {
              ListNode nextTemp = current.next;
              current.next = prev;
              prev = current;
              current = nextTemp;
          }
          return prev;
      }
      
  3. 合并两个有序数组(Merge Sorted Arrays)

    • 目标:将两个有序数组合并成一个有序数组。
    • 解题思路:从后往前遍历两个数组,依次比较较大的元素放入合并后的数组的末尾。
    • 代码示例:
      public void merge(int[] nums1, int m, int[] nums2, int n) {
          int i = m - 1;
          int j = n - 1;
          int k = m + n - 1;
          while (i >= 0 && j >= 0) {
              if (nums1[i] > nums2[j]) {
                  nums1[k--] = nums1[i--];
              } else {
                  nums1[k--] = nums2[j--];
              }
          }
          while (j >= 0) {
              nums1[k--] = nums2[j--];
          }
      }
      
  4. 快速排序(Quick Sort)

    • 目标:将数组排序。
    • 解题思路:选择一个基准元素,将数组分成小于基准和大于基准的两部分,然后递归地对这两部分进行快速排序。
    • 代码示例:
      public void quickSort(int[] arr, int low, int high) {
          if (low < high) {
              int pivotIndex = partition(arr, low, high);
              quickSort(arr, low, pivotIndex - 1);
              quickSort(arr, pivotIndex + 1, high);
          }
      }
      
      private int partition(int[] arr, int low, int high) {
          int pivot = arr[high];
          int i = low - 1;
          for (int j = low; j < high; j++) {
              if (arr[j] < pivot) {
                  i++;
                  swap(arr, i, j);
              }
          }
          swap(arr, i + 1, high);
          return i + 1;
      }
      
      private void swap(int[] arr, int i, int j) {
          int temp = arr[i];
          arr[i] = arr[j];
          arr[j] = temp;
      }
      
  5. 归并排序(Merge Sort)

    • 目标:将数组排序。
    • 解题思路:使用分治法,将数组逐步划分为更小的子数组,然后合并这些子数组,保证合并后的数组依然有序。
    • 代码示例:
      public void mergeSort(int[] arr, int left, int right) {
          if (left < right) {
              int mid = left + (right - left) / 2;
              mergeSort(arr, left, mid);
              mergeSort(arr, mid + 1, right);
              merge(arr, left, mid, right);
          }
      }
      
      private void merge(int[] arr, int left, int mid, int right) {
          int[] temp = new int[right - left + 1];
          int i = left;
          int j = mid + 1;
          int k = 0;
          while (i <= mid && j <= right) {
              if (arr[i] < arr[j]) {
                  temp[k++] = arr[i++];
              } else {
                  temp[k++] = arr[j++];
              }
          }
          while (i <= mid) {
              temp[k++] = arr[i++];
          }
          while (j <= right) {
              temp[k++] = arr[j++];
          }
          System.arraycopy(temp, 0, arr, left, temp.length);
      }
      
  6. 二分查找(Binary Search)

    • 目标:在有序数组中查找指定元素的位置。
    • 解题思路:通过不断缩小查找范围,每次比较中间元素与目标值的大小,以确定在左半部分还是右半部分继续查找。
    • 代码示例:
      public int binarySearch(int[] arr, int target) {
          int left = 0;
          int right = arr.length - 1;
          while (left <= right) {
              int mid = left + (right - left) / 2;
              if (arr[mid] == target) {
                  return mid;
              } else if (arr[mid] < target) {
                  left = mid + 1;
              } else {
                  right = mid - 1;
              }
          }
          return -1;
      }
      
  7. 斐波那契数列(Fibonacci Sequence)

    • 目标:求解斐波那契数列的第n项。
    • 解题思路:使用递归或动态规划,根

据前两项计算当前项的值。

  • 代码示例(递归):
    public int fibonacci(int n) {
        if (n <= 1) {
            return n;
        }
        return fibonacci(n - 1) + fibonacci(n - 2);
    }
    
  1. 最长公共子序列(Longest Common Subsequence)

    • 目标:找出两个字符串的最长公共子序列。
    • 解题思路:使用动态规划,构建一个二维数组,记录两个字符串的所有子问题的解。
    • 代码示例:
      public int longestCommonSubsequence(String text1, String text2) {
          int m = text1.length();
          int n = text2.length();
          int[][] dp = new int[m + 1][n + 1];
          for (int i = 1; i <= m; i++) {
              for (int j = 1; j <= n; j++) {
                  if (text1.charAt(i - 1) == text2.charAt(j - 1)) {
                      dp[i][j] = dp[i - 1][j - 1] + 1;
                  } else {
                      dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
                  }
              }
          }
          return dp[m][n];
      }
      
  2. 动态规划背包问题(Knapsack Problem)

    • 目标:在给定一定容量的背包和一系列物品的情况下,选择一些物品使其价值最大化。
    • 解题思路:使用动态规划,构建一个二维数组,记录不同背包容量下选择不同物品的最大价值。
    • 代码示例:
      public int knapsack(int[] weights, int[] values, int capacity) {
          int n = weights.length;
          int[][] dp = new int[n + 1][capacity + 1];
          for (int i = 1; i <= n; i++) {
              for (int j = 1; j <= capacity; j++) {
                  if (weights[i - 1] <= j) {
                      dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weights[i - 1]] + values[i - 1]);
                  } else {
                      dp[i][j] = dp[i - 1][j];
                  }
              }
          }
          return dp[n][capacity];
      }
      
  3. 最短路径算法(Dijkstra’s Algorithm)

    • 目标:在加权图中找到从一个节点到另一个节点的最短路径。
    • 解题思路:使用贪心算法,维护一个距离数组和一个标记数组,每次选择距离最短且未访问的节点进行松弛操作。
    • 代码示例:
      public int[] dijkstra(int[][] graph, int source) {
          int n = graph.length;
          int[] distances = new int[n];
          Arrays.fill(distances, Integer.MAX_VALUE);
          distances[source] = 0;
          boolean[] visited = new boolean[n];
          for (int i = 0; i < n - 1; i++) {
              int minDistance = Integer.MAX_VALUE;
              int minIndex = -1;
              for (int j = 0; j < n; j++) {
                  if (!visited[j] && distances[j] < minDistance) {
                      minDistance = distances[j];
                      minIndex = j;
                  }
              }
              visited[minIndex] = true;
              for (int j = 0; j < n; j++) {
                  if (!visited[j] && graph[minIndex][j] != 0 && distances[minIndex] != Integer.MAX_VALUE &&
                      distances[minIndex] + graph[minIndex][j] < distances[j]) {
                      distances[j] = distances[minIndex] + graph[minIndex][j];
                  }
              }
          }
          return distances;
      }
      
  4. 最大子数组和(Maximum Subarray Sum)

    • 目标:找到一个数组中连续子数组的最大和。
    • 解题思路:使用动态规划,依次遍历数组元素,维护一个当前子数组的最大和和一个全局的最大和。
    • 代码示例:
      public int maxSubArray(int[] nums) {
          int maxEndingHere = nums[0];
          int maxSoFar = nums[0];
          for (int i = 1; i < nums.length; i++) {
              maxEndingHere = Math.max(nums[i], maxEndingHere + nums[i]);
              maxSoFar = Math.max(maxSoFar, maxEndingHere);
          }
          return maxSoFar;
      }
      
  5. LRU缓存(Least Recently Used Cache)

    • 目标:实现一个LRU缓存结构,即在缓存满时,删除最近最少使用的数据。
    • 解题思路:使用哈希表和双向链表来实现缓存结构,每次访问数据时,将数据移到链表头部,当缓存满时,删除链表尾部的数据。
    • 代码示例:
      class LRUCache {
          private Map<Integer, Integer> cache;
          private LinkedList<Integer> keys;
          private int capacity;
      
          public LRUCache(int capacity) {
              this.cache = new HashMap<>();
              this.keys = new LinkedList<>();
              this.capacity = capacity;
          }
      
          public int get(int key) {
              if (!cache.containsKey(key)) {
                  return -1;
              }
              keys.remove((Integer) key);
              keys.addFirst(key);
              return cache.get(key);
          }
      
          public void put(int key, int value) {
              if (cache.containsKey(key)) {
                  keys.remove((Integer) key);
              } else if (cache.size() >= capacity) {
                  int lastKey = keys.removeLast();
                  cache.remove(lastKey);
              }
              cache.put(key, value);
              keys.addFirst(key);
          }
      }
      
  6. 判断链表是否有环(Detect Cycle in Linked List)

    • 目标:判断一个链表是否有环。

    • 解题思路:使用快慢指针,如果存在环,快指针最终会追上慢指针;如果不存在环,快指针会先到达链表末尾。

    • 代码示例:

      public boolean hasCycle(ListNode head) {
          if (head == null || head.next == null) {
              return false;
          }
          ListNode slow = head;
          ListNode fast = head.next;
          while (slow != fast) {
              if (fast == null || fast.next == null) {
                  return false;
              }
              slow = slow.next;
              fast = fast.next.next;
          }
          return true;
      }
      
  7. 树的遍历(Tree Traversals)

    • 目标:遍历树的所有节点。
    • 解题思路:树的遍历有前序、中序、后序和层次遍历。前序遍历首先访问根节点,然后递归遍历左右子树;中序遍历先遍历左子树,然后访问根节点,再遍历右子树;后序遍历先遍历左右子树,最后访问根节点;层次遍历从上到下逐层遍历。
    • 代码示例(前序遍历):
      public void preorderTraversal(TreeNode root) {
          if (root != null) {
              System.out.println(root.val);
              preorderTraversal(root.left);
              preorderTraversal(root.right);
          }
      }
      
  8. 求解平方根(Square Root)

    • 目标:实现求解一个数的平方根。
    • 解题思路:使用二分查找,查找平方根的近似值。
    • 代码示例:
      public double sqrt(double x) {
          double left = 0;
          double right = x;
          double epsilon = 1e-7;
          while (right - left > epsilon) {
              double mid = left + (right - left) / 2;
              if (mid * mid > x) {
                  right = mid;
              } else {
                  left = mid;
              }
          }
          return left;
      }
      
  9. 字符串反转(Reverse String)

    • 目标:将一个字符串进行反转操作。
    • 解题思路:使用双指针,交换头尾字符的位置,依次向中间靠拢。
    • 代码示例:
      public String reverseString(String s) {
          char[] chars = s.toCharArray();
          int left = 0;
          int right = chars.length - 1;
          while (left < right) {
              char temp = chars[left];
              chars[left] = chars[right];
              chars[right] = temp;
              left++;
              right--;
          }
          return new String(chars);
      }
      
  10. 字符串匹配算法(String Matching)

    • 目标:在文本中查找特定模式。
    • 解题思路:使用KMP算法(Knuth-Morris-Pratt算法),预处理模式串,构建部分匹配表,然后在文本串中进行匹配。
    • 代码示例(部分匹配表构建):
      public int[] buildPartialMatchTable(String pattern) {
          int[] table = new int[pattern.length()];
          int j = 0;
          for (int i = 1; i < pattern.length(); i++) {
              while (j > 0 && pattern.charAt(i) != pattern.charAt(j)) {
                  j = table[j - 1];
              }
              if (pattern.charAt(i) == pattern.charAt(j)) {
                  j++;
              }
              table[i] = j;
          }
          return table;
      }
      
  11. 最长上升子序列(Longest Increasing Subsequence)

    • 目标:找出数组中最长的上升子序列的长度。
    • 解题思路:使用动态规划,维护一个数组,记录以每个元素结尾的最长上升子序列长度。
    • 代码示例:
      public int longestIncreasingSubsequence(int[] nums) {
          int n = nums.length;
          int[] dp = new int[n];
          Arrays.fill(dp, 1);
          for (int i = 1; i < n; i++) {
              for (int j = 0; j < i; j++) {
                  if (nums[i] > nums[j]) {
                      dp[i] = Math.max(dp[i], dp[j] + 1);
                  }
              }
          }
          int maxLength = 0;
          for (int len : dp) {
              maxLength = Math.max(maxLength, len);
          }
          return maxLength;
      }
      
  12. 滑动窗口算法(Sliding Window)

    • 目标:用于解决一些数组/字符串相关的问题,如最小覆盖子串、最长连续子数组等。
    • 解题思路:使用双指针,通过滑动窗口来在数组/字符串上移动,以解决特定问题。
    • 代码示例(最小覆盖子串):
      public String minWindowSubstring(String s, String t) {
          int[] targetFreq = new int[128];
          for (char c : t.toCharArray()) {
              targetFreq[c]++;
          }
          int left = 0;
          int right = 0;
          int minLen = Integer.MAX_VALUE;
          int minStart = 0;
          int count = t.length();
          while (right < s.length()) {
              if (targetFreq[s.charAt(right)] > 0) {
                  count--;
              }
              targetFreq[s.charAt(right)]--;
              right++;
              while (count == 0) {
                  if (right - left < minLen) {
                      minLen = right - left;
                      minStart = left;
                  }
                  targetFreq[s.charAt(left)]++;
                  if (targetFreq[s.charAt(left)] > 0) {
                      count++;
                  }
                  left++;
              }
          }
          return minLen == Integer.MAX_VALUE ? "" : s.substring(minStart, minStart + minLen);
      }
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楞敲小青年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值