编程题(一)

目录

一、数组中重复的数字

二、寻找目标值 —— 二维数组

三、替换空格

四、从尾到头打印链表

一、数组中重复的数字

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组[2,3,1,0,2,5,3],那么对应的输出是2或者3。存在不合法的输入的话输出-1。

示例:

输入:  [2,3,1,0,2,5,3]

返回值: 2

说明: 2或3都是对的

数据范围:0 ≤ n ≤ 10000

点击这里去做题

解题思路一:

不断交换数组下标和元素,使得元素的值与下标相等。交换的过程中,如果发现已有元素的值和下标相等,则将该重复的元素返回。

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * @param numbers int整型一维数组
     * @return int整型
     */
    public int duplicate (int[] numbers) {
        if (numbers == null || numbers.length == 0) {
            return -1;
        }
        for (int i = 0; i < numbers.length; ++i) {
            while (i != numbers[i]) {
                if (numbers[i] == numbers[numbers[i]]) {
                    return numbers[i];
                }

                int temp = numbers[i];
                numbers[i] = numbers[temp];
                numbers[temp] = temp;
            }
        }
        return -1;
    }
}

时间复杂度o(n),空间复杂度o(1)

解题思路二:创建一个哈希表,依次遍历元素,如果该元素不存在表中,将该元素加入;如果存在,则将该元素返回。

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * @param numbers int整型一维数组 
     * @return int整型
     */
    public int duplicate (int[] numbers) {
       HashSet<Integer> hashset = new HashSet<>();
       for(int i : numbers){
            if(hashset.contains(i)){
                return i;
            }
            hashset.add(i);
       }
        return -1;
    }
}

时间复杂度o(n),空间复杂度o(n)

二、寻找目标值 —— 二维数组

在一个n*md的二维数组 plants 记录了园林景观的植物排布情况,具有以下特性:

  • 每行中,每棵植物的右侧相邻植物不矮于该植物;
  • 每列中,每棵植物的下侧相邻植物不矮于该植物。

请判断 plants 中是否存在目标高度值 target

示例

输入:plants = [[2,3,6,8],[4,5,8,9],[5,9,10,12]], target = 8

输出:true
输入:plants = [[1,3,5],[2,5,7]], target = 4

输出:false

数据范围: 0 <= n <= 1000    0 <= m <= 1000

​​​​​​点击这里去做题

解题思路一:

如果将二维数组元素的值类比成我们可以看得见的颜色,数值越大颜色越深。

我们可以得出:当元素位于二维数组越靠左上的位置,值越小;越靠右下的位置值越大。

以左下角的元素为坐标原点,建立一个二维直角坐标系,列用col表示,行用row表示。

从左下角开始遍历整个数组,如果一个数比左下角元素小,col+1;比左下角元素大,row+1。

class Solution {
    public boolean findTargetIn2DPlants(int[][] plants, int target) {
        if(plants == null || plants.length == 0 || plants[0].length ==0){
            return false;
        }
        int rows = plants.length;   //总共的行数
        int cols = plants[0].length;    //总共的列数

        //以左下角为起点遍历二维数组
        int row = rows -1;
        int col = 0;
        while(row >=0 && col <= cols-1 ){
            if(target > plants[row][col]){
                col++;
            }else if(target < plants[row][col]){
                row--;
            }else{
                return true;
            }
        }
        return false;
    }
}

时间复杂度o(n+m),空间复杂度o(1)

解题思路二:

本题没有确保每行的第一个整数大于前一行的最后一个整数,因此我们无法采取两次二分的做法。

只能遍历行或列,然后再对列或行进行二分查找。

class Solution {
    public boolean findTargetIn2DPlants(int[][] plants, int target) {
        if(plants == null || plants.length == 0 || plants[0].length ==0){
            return false;
        }
        int rows = plants.length;   //总共的行数
        int cols = plants[0].length;    //总共的列数

      for(int i = 0; i < rows; ++i){    //遍历行
        int low = 0,high = cols -1;    
        while(low <= high ){   //对列进行二分查找
            int mid = (low+high) >> 1;
            if(plants[i][mid] > target){
                high = mid -1;
            }else if(plants[i][mid] < target){
                low = mid +1;
            }else{
                return true;
            }
        }
    }
         return false;
    }
}

时间复杂度:O(mlogn) 或 O(nlog⁡m),空间复杂度:O(1)

三、替换空格

点击这里去做题

解题思路一:

利用StringBuilder的append方法,当遇到空格时,向其添加“%20”;当遇到非空格时,向其添加该元素,最后再转化成字符串类型。

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * @param s string字符串 
     * @return string字符串
     */
    public String replaceSpace (String s) {
        StringBuilder sd = new StringBuilder();
        for(int i = 0; i < s.length(); ++i){
            if(s.charAt(i) == ' '){
                sd.append("%20");
            }else{
                sd.append(s.charAt(i));
            }
        }
        return sd.toString();
    }
}

时间复杂度o(n),空间复杂度o(n)

解题思路二:

一个空格占用一个空间,%20占用三个空间。所以替换后的字符串长度 = 原来的字符串长度 + 空格个数 *2 。由于Java中不能实现自动扩容,所以需要新建一个字符数组(C++不用),遍历原来的字符串,当遇到空格时,向其添加“%20”;当遇到非空格时,向其添加该元素,最后再转化成字符串类型。

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * @param s string字符串 
     * @return string字符串
     */
    public String replaceSpace (String s) {
        int count = 0;  //用来记录空格个数
        for(int i = 0;i < s.length(); ++i){
            if(s.charAt(i) ==  ' ')
                count++;
        }
        char res[] = new char[s.length()+ count *2];
        int k = 0;
        for(int i = 0; i < s.length(); i++){
            if(s.charAt(i) == ' '){
                res[k++] = '%';
                res[k++] = '2';
                res[k++] = '0';
            }else{
                res[k++] = s.charAt(i);
            }
        }

        return new String(res);
    }
}

时间复杂度o(n),空间复杂度o(n)

四、从尾到头打印链表

点击这里去做题

解题思路一:

创建一个ArrayList,,每一次都向ArrayList的起始处增添元素。

import java.util.*;
/**
*    public class ListNode {
*        int val;
*        ListNode next = null;
*
*        ListNode(int val) {
*            this.val = val;
*        }
*    }
*
*/
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        if(listNode == null){
            return new ArrayList<>();
        }   
       
       ArrayList<Integer> list = new ArrayList<>();
       while(listNode != null){
            list.add(0,listNode.val);   //将listNode.val的值添加到list的开头
            listNode = listNode.next;
        }
        return list; 
    }
}

时间复杂度o(n),空间复杂度o(n)

解题思路二:

利用栈后进先出的特性,创建一个栈,先把遍历结果存入栈中,最后再弹出栈中元素。

import java.util.*;
/**
*    public class ListNode {
*        int val;
*        ListNode next = null;
*
*        ListNode(int val) {
*            this.val = val;
*        }
*    }
*
*/
import java.util.ArrayList;
public class Solution {
    public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
        ArrayList<Integer> list  = new ArrayList<>();
        Stack<Integer> stack = new Stack<>();
        while(listNode != null){
            stack.push(listNode.val);
            listNode = listNode.next;
        }
        while(!stack.empty()){
            list.add(stack.pop());
        }
        return list; 

    }
}

时间复杂度o(n),空间复杂度o(n)

感谢您的观看,希望你今天特别特别开心,加油~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值