首页 > 其他分享 >剑指offer_20230803

剑指offer_20230803

时间:2023-09-03 16:56:49浏览次数:42  
标签:数字 offer strArray pos 20230803 数组 逆序 left

剑指 Offer 51. 数组中的逆序对

题目说明

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

解题思路1:暴力

肯定是可行但是会超时的,就不用考虑了,但理论可行

解题思路2:归并

可以利用归并排序时的一个特性。当我们在并的阶段时,我们需要对左半边和右半边数组进行比较并且生成一个新的从小到大排序的数组。而我们在进行比较的时候,其实就相当于进行了逆序的判断:如果右半边数组比左半边小的话,则右边先进数组,说明这是一个逆序。我们可以计入逆序对总数count,要注意的是,当判定到此时left[i] > right[j]时,left后续的元素也是大于right[j]的,所以count += left.length - i

Picture1.png

剑指 Offer 45. 把数组排成最小的数

题目说明

输入一个非负整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。输出结果可能非常大,所以你需要返回一个字符串而不是整数

解题思路

其实同样也是一个排序,只是排序的方式变了。在这道题中,判定哪个数字小(或者说位置应该排在前面)比较的不是数字的大小也不是字符串的大小(因为“3”比“30”小但是应该“30”排在前面),因此这里用到了一个关键的比较逻辑:(a + b).compareTo(b + a),仍然以前面的“3”和“30”为例,“303”是小于“330”,在这个逻辑中可以得到体现。因此我们依照此逻辑写一个排序即可,本题使用了快排

复习一下快排。快排的核心思想是为设置好的数字(我设置为最左边的数字)找到合适的位置,升序排序的话则要保证该位置左边的数字都小于等于它而右边的数字都大于等于它,然后我们就可以对左右两边分别进行快排直到子数组中只有一个元素为止

在这道题中也是一样的道理,只是修改了比较大小的逻辑

while (true) {
    while (i < j && (strArray[j] + strArray[left]).compareTo(strArray[left] + strArray[j]) >= 0) {
        j--;
    }
    while (i < j && (strArray[i] + strArray[left]).compareTo(strArray[left] + strArray[i]) <= 0) {
        i++;
    }
    if (i >= j) {
        break;
    }

    tmp = strArray[i];
    strArray[i] = strArray[j];
    strArray[j] = tmp;
}
tmp = strArray[left];
strArray[left] = strArray[i];
strArray[i] = tmp;

大顶堆小顶堆

是基于完全二叉树进行构建的

image-20230803150153722

然后交换0和9(头和末尾),输出9。循环直到没有数组中没有元素为止。不用真的去构建一棵树,利用完全二叉树的性质

// 返回当前节点的父节点
private int parent(int pos) { return (pos - 1) / 2; }

// 返回当前节点的左子节点
private int leftChild(int pos) { return (2 * pos) + 1; }

// 返回当前节点的右子节点
private int rightChild(int pos) { return (2 * pos) + 2; }

标签:数字,offer,strArray,pos,20230803,数组,逆序,left
From: https://www.cnblogs.com/xccx-0824/p/17603417.html

相关文章

  • 剑指 Offer 57 - II. 和为s的连续正数序列(简单)
    题目:classSolution{public:vector<vector<int>>findContinuousSequence(inttarget){//本题使用滑动窗口(双指针)inti=1,j=1;//定义左右边界,一般是左闭右开intsum=0;//窗口内的和vector<vector<int>>result;whi......
  • 剑指 Offer 39. 数组中出现次数超过一半的数字(简单)
    题目:classSolution{public:intmajorityElement(vector<int>&nums){unordered_map<int,int>map;intresult;for(inti=0;i<nums.size();i++){map[nums[i]]++;}for(inti=0;i<n......
  • Leetcode 剑指 Offer 58 - II. 左旋转字符串(Zuo xuan zhuan zi fu chuan lcof)
    题目链接字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。示例1:输入:s="abcdefg",k=2输出:"cdefgab"示例2:输入:s=......
  • 剑指 Offer 44. 数字序列中某一位的数字(中等)
    题目:classSolution{//本题单纯找规律,要注意通过n%digits来判断有几个位数为digits的数public:intfindNthDigit(intn){longbase=9,digits=1;//digits代表位数while(n-base*digits>0){//该循环是为了确定目标数字所在数num......
  • 20230803模拟赛
    20230803模拟赛T1摆花sb结论题,考场上题读错了,我更是sb。直接输出最小区间长度。T2打饭题意给定\(n,k\)和序列\(a\)。求一个\(a\)的排列方式使得\[\sum_{i=1}^{n-k}|a_i-a_{i+k}|\]最小,输出这个最小值。题解可以转化成把\(n\)个数分成\(k\)组,且有\(n\bmod......
  • 剑指 Offer 48. 最长不含重复字符的子字符串 java
    请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。示例1:输入:"abcabcbb"输出:3解释:因为无重复字符的最长子串是"abc",所以其长度为3。示例2:输入:"bbbbb"输出:1解释:因为无重复字符的最长子串是"b",所以其长度为1。示例3:输入......
  • 剑指 Offer 14- II. 剪绳子 II(中等)
    题目:classSolution{//本题用贪心算法,拆成尽可能多的3且不可以出现长度为1的小段。用dp会溢出,放弃吧public:intcuttingRope(intn){if(n==2)return1;if(n==3)return2;if(n==4)return4;longlongres=1;......
  • 剑指 Offer 48. 最长不含重复字符的子字符串
    请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度。 示例 1:"abc",所以其示例2:"b"示例3:"wke""pwke" 提示:s.length<=40000使用滑动窗口,哈希表来记录:classSolution{publicintlengthOfLongestSubstring(Strings){HashMap<Ch......
  • 【剑指Offer】剑指offer题目汇总
    【剑指Offer】剑指offer题目汇总本文为《剑指Offer》刷题笔记的总结篇,花了两个多月的时间,将牛客网上《剑指Offer》的66道题刷了一遍,以博客的形式整理了一遍,这66道题属于相对基础的算法题目,对于刷题练手是很好的实践,接下来会继续回到LeetCode,争取每天拿出一个小时,刷一到两道题。......
  • 【剑指Offer】15、反转链表
    【剑指Offer】15、反转链表题目描述:输入一个链表,反转链表后,输出新链表的表头。解题思路:本题比较简单,有两种方法可以实现:(1)三指针。使用三个指针,分别指向当前遍历到的结点、它的前一个结点以及后一个结点。将指针反转后,三个结点依次前移即可。(2)递归方法。同样可以采用递归来实现......