剑指offer[57,57-2,58-1,58-2]

剑指 Offer 57. 和为s的两个数字

题目

在这里插入图片描述

思路

使用二分法中的对撞指针,对于nums[i]+nums[j]和大于target情况,则j–;小于target时i++;当相等的时候,返回数组

代码

class Solution {
    public int[] twoSum(int[] nums, int target) {
        int i=0,j=nums.length-1;
        while(i<j){
        //下面代码本来是想优化算法,但大部分时间还是增加运算时长,故去除
            // int m=(i+j)/2;
            // if(m>target) j=m-1;
            // if(m==target&&nums[0]==0){      
            //     return new int[]{0,m};      
            // }
            if((nums[i]+nums[j])>target) j=j-1;
            else if((nums[i]+nums[j])<target) i=i+1;
            else {
                return new int[]{nums[i],nums[j]};
            };
        }
        return new int[0];
    }
}
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        i,j=0,len(nums)-1
        while i<j :
            if (nums[i]+nums[j])>target:j=j-1
            elif (nums[i]+nums[j])<target:i=i+1
            else: return [nums[i],nums[j]]
        return []

剑指 Offer 57 - II. 和为s的连续正数序列

题目(使用滑动窗口解题)

在这里插入图片描述

代码

class Solution {
    public int[][] findContinuousSequence(int target) {
        // 使用滑动窗口解决连续大小的数组问题
        int i=1,j=1,res=0;
        List<int[]> ans=new ArrayList<>();

        while(i<=target/2){
            if(res<target){
                res+=j;
                j+=1;
            }else if(res>target){
                res-=i;
                i+=1;
            }else{
                int[] arr=new int[j-i];
                for(int k=i;k<j;k++){
                    arr[k-i] = k;
                }
                ans.add(arr);
                res-=i;
                i++;
            }
        }
        return ans.toArray(new int[ans.size()][]);
    }
}
class Solution:
    def findContinuousSequence(self, target: int) -> List[List[int]]:
        ans=[]
        i,j=1,1
        res=0
        # 因为数组为连续的数字,所以当i等于target/2时,i+1与i相加必定会超过target
        while i<=target//2:
            # 对于res小于target的情况,需要将j向右平移,同时res加上新增的数字
            # 为了编程的方便,滑动窗口一般表示成一个左闭右开区间(滑动窗口不包含j,即为不包含右边界)
            if res<target: 
                res=res+j
                j=j+1
            # 对于res大于target的情况,需要将i向右平移,同时res减去最开始的i数字
            elif res>target:
                res=res-i
                i+=1
            # 对于res等于target的情况,则放进列表中输出
            else:
                arr=list(range(i,j))
                ans.append(arr)
                res-=i
                i+=1
        return ans

剑指 Offer 58 - I. 翻转单词顺序

题目

在这里插入图片描述

代码

class Solution {
    public String reverseWords(String s) {
        // 使用trim删除首尾空格,通过空格分割为字符串组
        String[] str=s.trim().split(" ");
        StringBuilder res=new StringBuilder();
        for(int i=str.length-1;i>=0;i--){
            // 对于两词之间多余的空格,分割出来为空字符串,识别并跳过本次循环,添加下一个字符串
            if(str[i].equals("")) continue;
            res.append(str[i]+" ");
        }
        return res.toString().trim();
    }
}
class Solution:
    def reverseWords(self, s: str) -> str:
        arr=s.split(' ')
        ans=''
        for i in range(len(arr)):
            if arr[len(arr)-i-1]=='':continue
            ans+=' '+arr[len(arr)-i-1]
        return ans.strip()

剑指 Offer 58 - II. 左旋转字符串

题目

在这里插入图片描述

代码

class Solution {
    public String reverseLeftWords(String s, int n) {
        // 方法一:使用切片工具直接提取
        // return s.substring(n,s.length())+s.substring(0,n);
        // 方法二:按位置循环取出相对应的字符
        StringBuilder sd=new StringBuilder();
        for(int i=n;i<n+s.length();i++){
            sd.append(s.charAt(i%s.length()));
        }
        return sd.toString();
    }
}
class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        # 方法一:使用切片工具
        # return s[n:]+s[:n]
        # 方法二:使用循环按位置拼接字符
        s=list(s)
        res=''
        for i in range(n,n+len(s)):
            res+=s[i%len(s)]
        return res
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值