算法练习及知识点

二分查找

框架(注意要确定查找区间,还有尽量使用else if来保证细节)
int binarySearch(int[] nums, int target) {
    int left = 0, right = ...;
    while(...) {
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) {
            ...
        } else if (nums[mid] < target) {
            left = ...
        } else if (nums[mid] > target) {
            right = ...
        }
    }
    return ...;
}
704. 二分查找
给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target ,如果目标值存在返回下标,否则返回 -1

AC:

class Solution {
    public int search(int[] nums, int target) {
        int max = nums.length-1;
        int min = 0;
        int m;
        while(min<max){
            m = min + (max-min)/2;  //m = min + (max - min) / 2;  没有“min+”也会超时
            if(target == nums[m]){
                return m;
            }
            if(target < nums[m]){
                max = m-1;
            }
            else{
                min = m+1;        //后来改成只有下面+1,上面没有-1也超时了
            }
        }
        return nums[min] == target ? min : -1;//这个直接写return就报错了。会有一些案例不通过
    }    
}
278 . 第一个坏版本
您是一名产品经理,目前正在领导一个团队开发新产品。不幸的是,您的产品的最新版本未通过质量检查。由于每个版本都是在前一个版本的基础上开发的,所以一个坏版本之后的所有版本也是坏的。
假设你有n 版本[1, 2, ..., n] ,你想找出第一个坏的,导致后面所有的都是坏的。
您将获得一个bool isBadVersion(version) 返回是否version 坏的 API。实现一个函数来查找第一个错误的版本。您应该尽量减少对 API 的调用次数。
解题思路:
此题考查的还是二分查找法:如果isBadVersion(mid)为true,则要查找的位置必然小于等于mid,即high = mid;反之若为false,则查找的位置要大于mid,即 low = mid + 1;二分区间不断缩短直至low = high,这时的low/high即为答案。

原来没有用二分,超出时间限制了。。题意是要用二分才能

/* The isBadVersion API is defined in the parent class VersionControl.
      boolean isBadVersion(int version); */

public class Solution extends VersionControl {
    public int firstBadVersion(int n) {
        for(int i = 1; i<=n;i++){
            if(isBadVersion(i)){
             return i;
            }
        }
        return 0;
    }
}

AC:

/* The isBadVersion API is defined in the parent class VersionControl.
      boolean isBadVersion(int version); */

public class Solution extends VersionControl {
    public int firstBadVersion(int n) {
        int min = 1;
        int max = n;
        int m;
        while(min<max){
            m = min + (max-min)/2;
            if(isBadVersion(m)){
                max = m;
            }
            else if(!isBadVersion(m)){
                min = m+1;
            }
        }
        return min;
    }
}

双指针

189. 轮转数组
提示
中等1.7K
相关企业
给定一个整数数组 nums ,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。

示例 1:

输入: nums = [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]
示例 2:
输入:nums = [-1,-100,3,99], k = 2
输出:[3,99,-1,-100]
解释:
向右轮转 1 步: [99,-1,-100,3]
向右轮转 2 步: [3,99,-1,-100]
提示:
1 <= nums.length <= 10 5
-2 31 <= nums[i] <= 2 31 - 1
0 <= k <= 10 5

AC:

使用反转数组的方法

class Solution {
    public void rotate(int[] nums, int k) {
        k %= nums.length;
        reverse(nums, 0, nums.length - 1);
        reverse(nums, 0, k - 1);
        reverse(nums, k, nums.length - 1);
    }

    public void reverse(int[] nums, int start, int end) {
        while (start < end) {
            int temp = nums[start];
            nums[start] = nums[end];
            nums[end] = temp;
            start += 1;
            end -= 1;
        }
    }
}
作者:Esaka
链接:https://leetcode.cn/problems/rotate-array/solutions/790602/xuan-zhuan-shu-zu-by-esaka-f-vu56/
来源:力扣(LeetCode)
557. 反转字符串中的单词 III
简单525
相关企业
给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

示例 1:
输入:s = "Let's take LeetCode contest" 输出:"s'teL ekat edoCteeL tsetnoc"
示例 2:
输入: s = "God Ding" 输出:"doG gniD"

提示:
1 <= s.length <= 5 * 10 4
s 包含可打印的 ASCII 字符。
s 不包含任何开头或结尾空格。
s 至少 有一个词。
s 中的所有单词都用一个空格隔开。

AC:

两种方法可以将字符数组转为字符串

String b = new String(a);

String b = String.valueOf(a);

用到反转数组
class Solution {
    public String reverseWords(String s) {
        char a[] = s.toCharArray();//将字符串转为字符数组
        int start = 0;
        for(int i = 0;i<a.length;i++){
            if(a[i] == ' '){
                int end = i-1;//空格前的字符下标为end
                while(start<end){//反转字符数组
                    char temp = a[start];
                    a[start] = a[end];
                    a[end] = temp;
                    start++;
                    end--;
                }
                start = i+1;//start变为空格后一个字符下标
            }
            if(i == a.length - 1){//最后一个单词后面没有空格,要考虑这个情况
                int end = i;
                while(start<end){
                    char temp = a[start];
                    a[start] = a[end];
                    a[end] = temp;
                    start++;
                    end--;
                }
            }
        }
        // String b = new String(a);两种方法可以将字符数组转为字符串
        String b = String.valueOf(a);
        return b;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值