NKUSOFT 算法导论上机作业1

二分查找

总提交数: 978次通过数: 348次通过率: 35.58%

内存限制: 104857600(BYTE)时间限制: 5000(MS)输入限制: 1000()输出限制: 1000()

题目描述

给定一个元素升序的整型数组 T 和一个目标值 x  ,请使用二分查找法结合分治策略查找 T 中的 x,如果目标值存在输出下标,否则输出 -1。

输入的第一行为数组 T 的各个元素,输入的第二行为目标值 x。
 


 

样例输入输出

样例1

输入:

-1 0 1 3 6 10
6

输出:

4

样例2

输入:

-1 0 1 3 6 10
2

输出:

-1

#include<iostream>
#include<vector>
#include<string>
#include<sstream>
using namespace std;

int binarySearch(vector<int> nums, int num);

int main() {
    vector<int> nums;
    int num;
    string input;
    getline(cin, input);
    istringstream iss(input);
    int number;
    while (iss >> number) {
        nums.push_back(number); // 将读取到的数字添加到vector中
    }
    cin >> num;
    int index = binarySearch(nums, num);
    cout << index;
}

int binarySearch(vector<int> nums, int num){
    int r = nums.size();
    int l = 1;
    while (l <= r) {
        int m = (l + r) / 2;
        if (nums[m] == num)return m;
        else if (nums[m] > num)r = m - 1;
        else l = m + 1;
    }
    return -1;
}

找到数组中第k小的数

总提交数: 1847次通过数: 363次通过率: 19.65%

内存限制: 104857600(BYTE)时间限制: 200(MS)输入限制: 1000()输出限制: 1000()

题目描述

给定整型数组 S 和整数 k,S的长度为n,1<= k <= n,请使用分治算法输出数组中第 k 小的数。

输入的第一行为数组 S 的各个元素,输入的第二行为整数 k。

C++的时间限制为50ms,Java的时间限制为500ms。


 

样例输入输出

样例1

输入:

3 1 2 5 4 6
3

输出:

3

样例2

输入:

2 2 5 1 1 4 3 6 3
2

输出:

1

import java.util.Scanner;

import javax.management.openmbean.ArrayType;

import java.util.Arrays;
import java.util.Collections;
import java.util.ArrayList;
public class Main {
    
    public static int Select(int S[],int k){
        int groupnum=(S.length/5)+1;
        int sgroup[][]=new int[5][];
        for(int i=0;i<5;i++){
            sgroup[i]=new int[groupnum];
        }
        int marr[]=new int[groupnum];//中间行 不确定是否有用
        for(int i=0;i<groupnum;i++){
            ArrayList<Integer> arr = new ArrayList<Integer>();
            for(int j=0;j<5&&i*5+j<S.length;j++){
                arr.add(S[i*5+j]);
            }
            //int[] arr = {S[i*5], S[i*5+1], S[i*5+2], S[i*5+3],S[i*5+4]};
            // 对数组进行排序
            Collections.sort(arr);
            for(int j=0;j<5;j++){
                sgroup[j][i]=arr.get(4-j);
            }
            marr[i]=sgroup[2][i];
        }
        int m=Select(marr,marr.length/2+1);
        
        
        return 0;
    }
    //交换行
    void swapRows(int[][] array, int row1, int row2) {
        int[] temp = array[row1];
        array[row1] = array[row2];
        array[row2] = temp;
    }
    //交换列
    void swapColumns(int[][] array, int col1, int col2) {
        for (int i = 0; i < array.length; i++) {
            int temp = array[i][col1];
            array[i][col1] = array[i][col2];
            array[i][col2] = temp;
        }
    }
    
    static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    static int partition(int[] arr, int low, int high) {
        int pivot = arr[high]; // 选取最后一个元素作为基准
        int i = (low - 1); // 设置小于基准的元素的索引

        for (int j = low; j < high; j++) {
            if (arr[j] <= pivot) {
                i = i + 1;
                swap(arr, i, j);
            }
        }
        swap(arr, i + 1, high); // 将基准值放到正确的位置
        return i + 1; // 返回基准值的最终索引,即中位数所在位置(对于偶数长度数组,中位数是该位置及其左侧位置的平均值)
    }
    // 查找中位数
    static double findMedian(int[] arr) {
        int n = arr.length;
        int mid = partition(arr, 0, n - 1);

        
        return arr[mid];
        
    }







    public static void main(String[] args) {
        int[]arr={6,9,7,5,1,3,4,8,2,0};
        

        Scanner scanner = new Scanner(System.in);
        
        String inputLine = scanner.nextLine();
        String inputkString = scanner.nextLine();
        int k = Integer.parseInt(inputkString);
        String[] numberStrings = inputLine.split(" ");
        int[] numbers = new int[numberStrings.length];
        for (int i = 0; i < numberStrings.length; i++) {
            try {
                numbers[i] = Integer.parseInt(numberStrings[i]);
            } catch (NumberFormatException e) {
                System.out.println("无效的输入: " + numberStrings[i] + " 无法转换为整数,将忽略此输入项");
            }
        }
        int result=KthSmallest.findKthSmallest(numbers, k-1);
        System.out.println(result);

    }
}
    
class KthSmallest {
    public static int findKthSmallest(int[] nums, int k) {
        return quickSelect(nums, 0, nums.length - 1, k);
    }

    private static int quickSelect(int[] nums, int left, int right, int k) {
        if (left == right) {
            return nums[left];
        }
        
        int pivotIndex = partition(nums, left, right);
        
        // Pivot is in its final sorted position
        if (k == pivotIndex) {
            return nums[k];
        } else if (k < pivotIndex) {
            // The kth smallest is in the left part
            return quickSelect(nums, left, pivotIndex - 1, k);
        } else {
            // The kth smallest is in the right part
            return quickSelect(nums, pivotIndex + 1, right, k);
        }
    }

    private static int partition(int[] nums, int left, int right) {
        int pivot = nums[right]; // 使用最后一个元素作为基准
        int i = left - 1;

        for (int j = left; j < right; j++) {
            if (nums[j] <= pivot) {
                i++;
                swap(nums, i, j);
            }
        }

        swap(nums, i + 1, right);

        return i + 1;
    }

    private static void swap(int[] nums, int i, int j) {
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值