LeetCode简单题(三)

题目一:

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

注意你不能在买入股票前卖出股票。 

示例 1:

输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。

方法一:

1、暴力法,用双循环将所有遍历情况都求出来,求出最大值

具体代码:

class Solution {
    public int maxProfit(int[] prices) {
        
        int ans=0;       
        for(int i=0;i<prices.length;i++)
            for(int j=i;j<prices.length;j++)
            {
                ans=Math.max(ans, prices[j]-prices[i]);
            }
if(ans<0) return 0; else { return ans; } } }

方法二:

求出最小值,然后从最小值后求出最大值

具体代码:

class Solution {
    public int maxProfit(int[] prices) {
        
        int minValue=Integer.MAX_VALUE;
        int maxPro=0;
        
        for(int i=0;i<prices.length;i++)
        {
            if(prices[i]<minValue)
                minValue=prices[i];
            else if (prices[i]-minValue>maxPro)
            {
                maxPro=prices[i]-minValue;
            }
        }        
        return maxPro;
    }
}

题目二:

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。

示例 1:

输入: [1,2,3,1]
输出: 4
解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
        偷窃到的最高金额 = 1 + 3 = 4 。

方法:

1、使用动态规划,先比较前三个数;

2、如果只有一个数,最大值为第一个数;如果有两个数,最大值为两个中最大的数;如果有三个数,则为dp[i]=Math.max(dp[i-2]+nums[i-1],dp[i-1])

具体代码:

class Solution {
    public int rob(int[] nums) {
        
        int len=nums.length;
        int[] dp=new int[len];
        dp[0]=0;
        dp[1]=nums[1];
        
        for(int i=0;i<=len;i++)
        {
            dp[i]=Math.max(nums[i]+dp[i-2], dp[i-1]);
        }
        return dp[len];        
    }
}

题目三:

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:

输入: [0,1,0,3,12]
输出: [1,3,12,0,0]

方法:

1、先将非0元素放置在最前面,后面元素都用0表示;

具体代码:

class Solution {
    public void moveZeroes(int[] nums) {
        
        int i=0;
        for(int j=0;j<nums.length;j++)
        {
            if(nums[j]!=0)
            {
                nums[i]=nums[j];
                i++;
            }
        }
        
        for(int p=i;p<nums.length;p++)
            nums[p]=0;
    }
}

题目四:

给定一个数组,将数组中的元素向右移动 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]

方法一:

1、暴力法先实现如何移动一位,让最后一个元素和第一个元素进行交换;

2、再进行第二个元素和最后一位进行交换,循环n次,就实现了移动一位;

3、整体进行k次循环,实现移动k位;

4、在学习编程思想当中,有一条一定记得:一定要把大的多的问题划分成小的问题,可能就找到的解题思路。

具体代码:

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

方法二:

1、新建一个数组,用于存储旋转后的元素

2、如何实现旋转后的元素,在循环a[i+k%num.lenght],这一步太巧妙了,实现了元素的k位旋转;

3、最后循环nums[i]=a[i]

具体代码

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];
        }
    }
}

方法三:

反转:

具体代码:

class Solution {
    public void rotate(int[] nums, int k) {
        
        k%=nums.length;
        
        reverse(nums,0,nums.length-1);
        reverse(nums,0,k);
        reverse(nums,k+1,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++;
            end--;
        }
    }
}

题目五:

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

说明:本题中,我们将空字符串定义为有效的回文串。

示例 1:

输入: "A man, a plan, a canal: Panama"
输出: true

方法:

1、使用双指针,一个头指针,一个尾指针,比较这两个字符;

2、这里有一个去除不是字符或者数字的操作,while(i<j&&Character.isLetterOrdigit(s.charAt(i))) i++/j--;

3、使用的while(i<j),如果第一个字符和最后一个字符相同,则i++,j--;

具体代码:

    public boolean isPalindrome(String s) {
        
        int i=0,j=s.length()-1;       
        while(i<j)
        {
            while((i<j)&&!Character.isLetterOrDigit(s.charAt(i))) i++;
            while((i<j)&&!Character.isLetterOrDigit(s.charAt(j))) j--;
            
            if(Character.toLowerCase(s.charAt(i))!=Character.toLowerCase(s.charAt(j)))
                return false;
            i++;
            j--;
        }
        return true;
    }
}

题目六:

牛牛总是睡过头,所以他定了很多闹钟,只有在闹钟响的时候他才会醒过来并且决定起不起床。从他起床算起他需要X分钟到达教室,上课时间为当天的A时B分,请问他最晚可以什么时间起床

输入描述:

每个输入包含一个测试用例。
每个测试用例的第一行包含一个正整数,表示闹钟的数量N(N<=100)。
接下来的N行每行包含两个整数,表示这个闹钟响起的时间为Hi(0<=A<24)时Mi(0<=B<60)分。
接下来的一行包含一个整数,表示从起床算起他需要X(0<=X<=100)分钟到达教室。
接下来的一行包含两个整数,表示上课时间为A(0<=A<24)时B(0<=B<60)分。
数据保证至少有一个闹钟可以让牛牛及时到达教室。

输出描述:

输出两个整数表示牛牛最晚起床时间。

方法:

将小时和分钟进行合并,对数组进行排序,然后进行二分查找,返回其下标

具体代码:

public class Main{
    
    public static void main(String[] args)
    {
        Scanner input=new Scanner(System.in);
        int n=input.nextInt();
        int h=0,m=0;
        int[] a=new int[n];
        
        for(int i=0;i<n;i++)
        {
            h=input.nextInt();
            m=input.nextInt();
            a[i]=h*60+m;
        }
        
        int t=input.nextInt();
        h=input.nextInt();
        m=input.nextInt();
        Arrays.sort(a);
        int p=h*60+m-t;
        
        t=Arrays.binarySearch(a, p);
        h=a[t]/60;
        m=a[t]%60;
        System.out.println(h+" "+m);
    }
}

题目七:

实现 int sqrt(int x) 函数。

计算并返回 x 的平方根,其中 x 是非负整数。

由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。

示例 1:

输入: 4
输出: 2

方法:

二分查找

具体代码:

class Solution {
    public int mySqrt(int x) {
        
        if(x==0)
            return 0;
        
        long left=1;
        long right=x/2;
        
        while(left<right)
        {
            long  mid=(left+right+1)>>>1;
            long  squa=mid*mid;
            
            if(squa>x)
                right=mid-1;
            else {
                left=mid;
            }
        }       
        return (int)left;
    }
}

题目八:

给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。

示例 1:

输入: "Let's take LeetCode contest"
输出: "s'teL ekat edoCteeL tsetnoc" 

方法:

1、将字符串转化为字符串数组,转化方式比较巧妙,String[] sp=s.split(" "),字符串数组

2、建立数组类型StringBuilder较为方便,直接append()元素

3、构建一个循环,循环中在构建一个变量StringBuilder t=ap[i]将其反转,最后再添加append();

4、返回的数据类型为string,需要将StringBuilder转化为string,sp.substring(0,sp.legth()-1);

具体代码:

class Solution {
    public String reverseWords(String s) {
        
        String[] strings=s.split(" ");
        StringBuilder sBuilder=new StringBuilder();
        
        for(int i=0;i<strings.length;i++)
        {
            StringBuilder tBuilder=new StringBuilder();
            tBuilder.append(strings[i]);
            sBuilder.append(tBuilder.reverse().toString()).append(" ");
        }
        
        return sBuilder.substring(0,sBuilder.length()-1);
    }
}

题目九:

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

在杨辉三角中,每个数是它左上方和右上方的数的和。

示例:

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

方法:

1、刚开始可能感觉不太好做,List<List<Integer>> traingle=new ArrayList<>(),traingle.add(new ArrayList<>()), traingle.get(0).add(1)

2、每个数组进行循环,有一点思维应该建立,循环里面设置变量,让每次循环的值发生改变;

3、for(int i=1;i<rownums;i++) List<Integer> row=new ArrayList<>(); List<Integer> prerow=traingle.get(i-1);

4、然后进行添加元素,row.add(1),通过prerow求出row;

5、for(int j=1;j<i;j++) row.add(prerow.get(j-1)+prerow.get(j));row.add(1);

6、最后将trangle.add(row);

具体代码:

class Solution {
    public List<List<Integer>> generate(int numRows) {
        
        List<List<Integer>> traigle=new ArrayList<>();
        if(numRows==0)
            return traigle;
        
        traigle.add(new ArrayList<>());
        traigle.get(0).add(1);
        
        for(int i=1;i<numRows;i++)
        {
            List<Integer> row=new ArrayList<>();
            List<Integer> prerow=traigle.get(i-1);
            
            row.add(1);
            for(int j=1;j<i;j++)
            {
                row.add(prerow.get(j-1)+prerow.get(j));
            }
            
            row.add(1);
            
            traigle.add(row);
        }       
        return traigle;
    }
}

题目十:

删除链表中等于给定值 val 的所有节点。

示例:

输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5

具体代码:

class Solution {
    public ListNode removeElements(ListNode head, int val) {
        
        ListNode dummy=new ListNode(0);
        dummy.next=head;
        ListNode curr=dummy;
        
        while(curr.next!=null)
        {
            if(curr.next.val==val)
            {
                curr.next=curr.next.next;
            }
            else
            {
                curr=curr.next;
            }
        }       
        return dummy.next;
    }
}
原文地址:https://www.cnblogs.com/Optimism/p/11391358.html