算法-数组篇

 刷leetcode不知道从哪里刷起?? 来看看,我把刷题题目顺序都排好了,每道题还带详细题解!_代码随想录-CSDN博客_力扣刷题顺序

 

前言:

。。。补充中 

1. 二维数组在内存的地址空间是连续的吗?

二维数组其实是一个线性数组存放着“其他数组的首地址” 

2. 大数相加

设置一个进位标志carry。两个字符串都从后往前进行遍历,这样会很高效

public class Solution {
    public static void main(String[] args) {

        new Solution().addString("123", "234");
    }

    public String addString(String num1, String num2){

        int carry=0, i=num1.length()-1, j=num2.length()-1;
        StringBuilder stringBuilder = new StringBuilder();

        while (i>=0 || j>=0 || carry!=0){
            if (i>=0) {
                carry += num1.charAt(i--) - '0';
            }
            if (j>=0) {
                carry += num2.charAt(j--) - '0';
            }
            stringBuilder.append(carry%10);
            carry/=10;
        }
        System.out.println(stringBuilder.reverse());
        return stringBuilder.reverse().toString();
    }
}

3. 搜索插入的位置【二分查找】【其中核心就是:差一结束】

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

你可以假设数组中无重复元素。

示例 1:
输入: [1,3,5,6], 5
输出: 2

示例 2:
输入: [1,3,5,6], 2
输出: 1

示例 3:
输入: [1,3,5,6], 7
输出: 4

示例 4:
输入: [1,3,5,6], 0
输出: 0

//1,3,5,6   2
    public int insertData(int[] array, int n){
        int start=0, end=array.length-1;
        int mid = 0;
        while (start<end){
            mid = (start+end)/2;
            if (array[mid] > n){
                end = mid;
            }else {
                start= mid;
            }
            if (start == end-1){
               break;
            }
        }
        if (n <= array[start]){
            return start;
        }
        if (n > array[end]){
            return end+1;
        }
        return end;
    }

4. 移除元素【快慢指针】【核心:快指针每一次都要后移、交换】

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。

不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并「原地」修改输入数组。

元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

示例 1:
给定 nums = [3,2,2,3], val = 3,
函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。
你不需要考虑数组中超出新长度后面的元素。

示例 2:
给定 nums = [0,1,2,2,3,0,4,2], val = 2,
函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。

//[3, 2, 2, 3]
    public int removeData(int array[], int val){

        int slow =0, fast = 0;
        while (fast < array.length){
            if (array[fast] != val){
                int tmp = array[fast];
                array[fast] = array[slow];
                array[slow] = tmp;
            }
            if (array[slow] != val){
                slow++;
            }
            fast ++;
        }
        return slow;
    }

5. 长度最小的子数组【滑动窗口】【核心:第一个提前加和】

给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。

示例:
输入:s = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

public int handleArray(int[] array, int n) {
        if (array == null){
            return 0;
        }

        int slow=0, fast = 0;
        int tmp = array[fast];
        int res = array.length;
        while (fast < array.length){
            if (tmp < n){
                fast++;
                if (fast == array.length){
                    break;
                }
                tmp += array[fast];

            }else {
                res = Math.min(fast-slow+1, res);
                tmp-=array[slow];
                slow++;
            }
            if (slow == fast){
                return 1;
            }
        }
        return res;
    }

6. 寻找旋转排序数组中的最小值【注意有序。。。二分切法】

已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7] 在变化后可能得到:
若旋转 4 次,则可以得到 [4,5,6,7,0,1,2]
若旋转 7 次,则可以得到 [0,1,2,4,5,6,7]
注意,数组 [a[0], a[1], a[2], ..., a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]] 。

给你一个元素值 互不相同 的数组 nums ,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。

输入:nums = [3,4,5,1,2]
输出:1
解释:原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。
输入:nums = [4,5,6,7,0,1,2]
输出:0
解释:原数组为 [0,1,2,4,5,6,7] ,旋转 4 次得到输入数组。

class Solution {
    // {3, 4, 5, 1, 2}
    public int findMin(int[] nums) {
        
        int start = 0, end = nums.length-1;

        if (nums[start] <= nums[end]){
            return nums[start];
        }
        while (start != end -1){
            int mid = (start + end)/2;
            if (nums[mid] > nums[start]){
                start = mid;
            }else {
                end = mid;
            }
        }
        if (nums[start] > nums[end]){
            return nums[end];
        }
        return nums[start];
    }
}

7.  无重复字符的最长子串【滑动窗口-HahsMap】

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

输入: s = "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 

输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

public int lengthOfLongestSubstring(String s){
        HashMap<Character, Integer> map = new HashMap<>();

        int maxLen = 0;//用于记录最大不重复子串的长度
        int left = 0;//滑动窗口左指针

        for (int i=0; i<s.length(); i++){
            if (map.containsKey(s.charAt(i))){
                left = Math.max(left, map.get(s.charAt(i)) + 1);
            }
            map.put(s.charAt(i), i);
            maxLen = Math.max(maxLen, i-left+1);
        }
        return maxLen;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值