算法收集(基于:java.util.ArrayList)

1、两数之和:

题目:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍

方法一:

public static int[] twoSum1(int[] nums, int target){
   Map<Integer, Integer> map = new HashMap<>();
   for (int i = 0; i < nums.length; i++) {
      map.put(nums[i], i);
   }
   for (int i = 0; i < nums.length; i++) {
      int complement = target - nums[i];
      if (map.containsKey(complement) && map.get(complement) != i) {
         return new int[] { i, map.get(complement) };
      }
   }
   throw new IllegalArgumentException("No two sum solution");
}

方法二:
public static int[] twoSum2(int[] nums, int target){
      Map<Integer, Integer> map = new HashMap<>();
      for (int i = 0; i < nums.length; i++) {
         map.put(nums[i], i);
      }
      for (int i = 0; i < nums.length; i++) {
         int complement = target - nums[i];
         if (map.containsKey(complement) && map.get(complement) != i) {
            return new int[] { i, map.get(complement) };
         }
      }
      throw new IllegalArgumentException("No two sum solution");
}

方法三:

public int[] twoSum3(int[] nums, int target) {
   int m=0,n=0,k,board=0;
   int[] res=new int[2];
   int[] tmp1=new int[nums.length];
   System.arraycopy(nums,0,tmp1,0,nums.length);
   Arrays.sort(nums);
   for(int i=0,j=nums.length-1;i<j;){
      if(nums[i]+nums[j]<target){
         i++;
      }
         
      else if(nums[i]+nums[j]>target){
         j--;
      }
      else if(nums[i]+nums[j]==target){
         m=i;
         n=j;
         break;
      }
   }
   for(k=0;k<nums.length;k++){
      if(tmp1[k]==nums[m]){
         res[0]=k;
         break;
      }
   }
   for(int i=0;i<nums.length;i++){
      if(tmp1[i]==nums[n]&&i!=k){
         res[1]=i;
      }
         
   }
   return res;
}

2、删除排序数组中的重复项

题目:给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。(

给定数组 nums = [1,1,2], 

函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 [1,2]
方法一:
public int removeDuplicates(int[] nums) {
    if (nums.length == 0) return 0;
    int i = 0;
    for (int j = 1; j < nums.length; j++) {
        if (nums[j] != nums[i]) {
            i++;
            nums[i] = nums[j];
        }
    }
    return i + 1;
}

3、杨辉三角

题目:给定一个非负整数 numRows,生成杨辉三角的前 numRows 行:

方法一:

public static List<List<Integer>> method1(int numRows) {
   List<List<Integer>> triangle = new ArrayList<List<Integer>>();

   // First base case; if user requests zero rows, they get zero rows.
   if (numRows == 0) {
      return triangle;
   }

   // Second base case; first row is always [1].
   triangle.add(new ArrayList<>());
   triangle.get(0).add(1);

   for (int rowNum = 1; rowNum < numRows; rowNum++) {
      List<Integer> row = new ArrayList<>();
      List<Integer> prevRow = triangle.get(rowNum-1);

      // The first row element is always 1.
      row.add(1);

      // Each triangle element (other than the first and last of each row)
      // is equal to the sum of the elements above-and-to-the-left and
      // above-and-to-the-right.
      for (int j = 1; j < rowNum; j++) {
         row.add(prevRow.get(j-1) + prevRow.get(j));
      }

      // The last row element is always 1.
      row.add(1);

      triangle.add(row);
   }

   return triangle;
}

方法二:

public static List<List<Integer>> method2(int nums){
   List<List<Integer>> list = new ArrayList<>();
   for(int i = 0;i<nums;i++){
      List<Integer> inerList = new ArrayList<>();

         for(int j=0;j<=i;j++){
            if(j == 0 || i==j){
               inerList.add(1);
            }else{
            inerList.add(list.get(i-1).get(j-1)+list.get(i-1).get(j));
         }
      }


      list.add(inerList);
   }

   return list;
}

4、最大子序和

题目:给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:

输入: [-2,1,-3,4,-1,2,1,-5,4]
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

-----------------动态规则:Javascript--------------------------

var maxSubArray = function(nums) {
    let pre = 0, maxAns = nums[0];
    nums.forEach((x) => {
        pre = Math.max(pre + x, x);
        maxAns = Math.max(maxAns, pre);
    });
    return maxAns;
};

------------分治--------------------------

public int maxSubArray(int[] nums) {
   return maxSubArrayDivideWithBorder(nums, 0, nums.length-1);
}

private int maxSubArrayDivideWithBorder(int[] nums, int start, int end) {
   if (start == end) {
      // 只有一个元素,也就是递归的结束情况
      return nums[start];
   }

   // 计算中间值
   int center = (start + end) / 2;
   int leftMax = maxSubArrayDivideWithBorder(nums, start, center); // 计算左侧子序列最大值
   int rightMax = maxSubArrayDivideWithBorder(nums, center + 1, end); // 计算右侧子序列最大值

   // 下面计算横跨两个子序列的最大值

   // 计算包含左侧子序列最后一个元素的子序列最大值
   int leftCrossMax = Integer.MIN_VALUE; // 初始化一个值
   int leftCrossSum = 0;
   for (int i = center ; i >= start ; i --) {
      leftCrossSum += nums[i];
      leftCrossMax = Math.max(leftCrossSum, leftCrossMax);
   }

   // 计算包含右侧子序列最后一个元素的子序列最大值
   int rightCrossMax = nums[center+1];
   int rightCrossSum = 0;
   for (int i = center + 1; i <= end ; i ++) {
      rightCrossSum += nums[i];
      rightCrossMax = Math.max(rightCrossSum, rightCrossMax);
   }

   // 计算跨中心的子序列的最大值
   int crossMax = leftCrossMax + rightCrossMax;

   // 比较三者,返回最大值
   return Math.max(crossMax, Math.max(leftMax, rightMax));
}

5、旋转数组

题目:

给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。

示例 1:输入: [1,2,3,4,5,6,7] 和 k = 3
输出: [5,6,7,1,2,3,4]
解释:
向右旋转 1 步: [7,1,2,3,4,5,6]
向右旋转 2 步: [6,7,1,2,3,4,5]
向右旋转 3 步: [5,6,7,1,2,3,4]

方法一暴力:public class Solution {
    public void rotate(int[] nums, int k) {
        int temp, previous;
        for (int i = 0; i < k; i++) {
            previous = nums[nums.length - 1];
            for (int j = 0; j < nums.length; j++) {
                temp = nums[j];
                nums[j] = previous;
                previous = temp;
            }
        }
    }
}

方法 2:使用额外的数组public class Solution {
    public void rotate(int[] nums, int k) {
        int[] a = new int[nums.length];
        for (int i = 0; i < nums.length; i++) {
            a[(i + k) % nums.length] = nums[i];
        }
        for (int i = 0; i < nums.length; i++) {
            nums[i] = a[i];
        }
    }
}

方法 3:使用环状替换public class Solution {
    public void rotate(int[] nums, int k) {
        k = k % nums.length;
        int count = 0;
        for (int start = 0; count < nums.length; start++) {
            int current = start;
            int prev = nums[start];
            do {
                int next = (current + k) % nums.length;
                int temp = nums[next];
                nums[next] = prev;
                prev = temp;
                current = next;
                count++;
            } while (start != current);
        }
    }
}

来源:力扣(LeetCode)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值