笔试常考编程题(持续更新)

(更新完毕后会以题型划分)

1.链表的倒数第k个元素

(剑指Offer22)

  • 思路1:二次遍历:第一次统计链表长度 第二次根据运算得到最终位置(效率低)
  • 思路2:一次遍历双指针:快指针慢指针跨度始终为k,使用一个计数器记录快指针走出的步数,到达k之后慢指针开始走,快指针到达链表尾部时慢指针也到达了需要结点。
class Solution {
    
    
public:
    ListNode* getKthFromEnd(ListNode* head, int k) {
    
    
  //双指针法
        if(!head)
        return head;
        int road=0;//记录前驱指针走了几步
        ListNode *slow=head;
        while(head){
    
    
            head=head->next;
            road++;
            if(road>k)
                slow=slow->next;
        }
        return slow;
    }
};

2.求数组中的第K大数字

(leetcode 剑指Offer2:76)

  • 思路1:先排序,再计算得知,但是一般的面试都不会要求这么做
  • 思路2:这里使用堆排序

maxHeapify 函数实现了将指定节点 i 的子树构建成最大堆的操作。参数 a 是待构建的堆, heapSize 是堆的大小, l 和
r 分别表示节点 i 的左右孩子。
largest记录当前节点及其子节点中值最大的节点的下标,然后交换该节点和根节点,递归地调整交换后新的根节点,以保证堆的性质。

buildMaxHeap 函数用于初始化堆。从堆的中间节点向根节点遍历,每个节点调用 maxHeapify函数,以保证每个节点的子树都是最大堆。

findKthLargest 函数首先使用 buildMaxHeap函数初始化整个堆,然后从堆的最后一个节点开始向前遍历,每次将根节点和当前节点交换,并且缩小堆的大小,最后将第k大元素返回。

class Solution {
    
    
public:
    int findKthLargest(vector<int>& nums, int k) {
    
    
           int HeapSize=nums.size();
           InitHeap(nums,HeapSize); //先初始化一下堆
           for(int i=nums.size() - 1;i >= nums.size() - k + 1; --i){
    
    
             swap(nums[0], nums[i]);
                --HeapSize;
                ModifyHeap(nums,0,HeapSize);
           }
              return nums[0];
    }

//调整堆
    void ModifyHeap(vector<int>& a,int i,int HeapSize){
    
     //i用来表示当前处理的元素,
      int lchild=i*2+1;
      int rchild=i*2+2;

      int largeNum=i; //largeNum用来排序过程中的最大元素
       
      //对于当前元素,开始与左右孩子比较
      if(lchild<HeapSize&&a[lchild] > a[largeNum]){
    
    
          largeNum=lchild;
      }
      if(rchild<HeapSize&&a[rchild] > a[largeNum]){
    
    
          largeNum=rchild;
      }
      if(largeNum!=i){
    
     //如果最大元素不在当前元素
         swap(a[largeNum],a[i]);
             ModifyHeap(a,largeNum,HeapSize);
         
      }
    }

    //初始化堆

    void InitHeap(vector<int>& a,int HeapSize){
    
    
         for(int i=HeapSize/2;i>=00;--i){
    
    
             ModifyHeap(a,i,HeapSize);//为每个父节点构建堆
         }
    }


};

3.最长连续递增(子)序列

(leetcode 674)

给定一个未经排序的整数数组,找到最长且 连续递增的子序列,并返回该序列的长度。连续递增的子序列 可以由两个下标 l 和 r(l < r)确定,如果对于每个 l <= i < r,都有 nums[i] < nums[i + 1] ,那么子序列 [nums[l], nums[l + 1], …, nums[r - 1], nums[r]] 就是连续递增子序列。
输入:nums = [1,3,5,4,7]
输出:3
解释:最长连续递增序列是 [1,3,5], 长度为3。
尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为 5 和 7 在原数组里被 4 隔开。
输入:nums = [2,2,2,2,2]
输出:1
解释:最长连续递增序列是 [2], 长度为1。

这道题是要求连续的子数列,如果是非连续就难一点了,可能需要动态规划
这道题一次遍历就可以解决

class Solution {
    
    
public:
    int findLengthOfLCIS(vector<int>& nums) {
    
    
        int maxLen = 0;
        int n = nums.size();
        int start = 0;
        for (int i = 0; i < n; i++) {
    
    
            if (i > 0 && nums[i] <= nums[i - 1]) {
    
    
                start = i;
            }
            maxLen = max(maxLen, i - start + 1);
        }
        return maxLen;
    }
};

4.原地判断回文链表

(leetcode 234)

  • 思路:这道题的核心思路是将链表分成两个部分,将后半部分逆置,然后逐字比较,这个思想非常重要,我们后面有道题也会用到这个
class Solution {
    
    
public:
    bool isPalindrome(ListNode* head) {
    
    
        if (!head) return true;
        ListNode *slow = head;
        ListNode *fast = head;
        while (fast->next != NULL && fast->next->next != NULL) {
    
    
            fast = fast->next->next;
            slow = slow->next;
        }
        ListNode *cur = NULL;
        if (slow->next) {
    
    
            cur = slow->next;
        } else {
    
    
            cur = slow;
        }
        ListNode *pre = NULL;
        ListNode *preMove = NULL;
        while (cur) {
    
    
            preMove = cur->next;
            cur->next = pre;
            pre = cur;
            cur = preMove;
        }
        while (head && pre) {
    
    
            if (head->val != pre->val) {
    
    
                return false;
            }
            head = head->next;
            pre = pre->next;
        }
        return true;
    }
};

5.顺时针90度旋转矩阵

(LeetCode 面试题 01.07. 旋转矩阵)

给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。

不占用额外内存空间能否做到?

给定 matrix =
[
[1,2,3],
[4,5,6],
[7,8,9]
],
原地旋转输入矩阵,使其变为:
[
[7,4,1],
[8,5,2],
[9,6,3]
]

思路:常规方法是找到对应元素的数学规律,但这种方法在考场上不好想到,还容易产生数组越界,这里提供一个简便算法:先按照行对称翻转,然后再让元素按对角线翻转

给定 matrix = 
[
  [1,2,3],
  [4,5,6],
  [7,8,9]
],

原地旋转输入矩阵,使其变为:
[
  [7,4,1],
  [8,5,2],
  [9,6,3]
]

6.旋转数组的最小数字

把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。
给你一个可能存在 重复 元素值的数组 numbers ,它原来是一个升序排列的数组,并按上述情形进行了一次旋转。请返回旋转数组的最小元素。例如,数组 [3,4,5,1,2] 为
[1,2,3,4,5] 的一次旋转,该数组的最小值为 1。
注意,数组 [a[0], a[1], a[2], …, a[n-1]] 旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], …, a[n-2]] 。

  • 思路:这道题是利用二分查找以及当前元素和Nums[mid]的关系
class Solution {
    
    
public:
    int minArray(vector<int>& numbers) {
    
    
          int end=numbers.size()-1;
          int high=end;
         int low=0;
         while(low<high){
    
    
             int mid=low+(high-low)/2; //防止溢出
             
             //情况一 在左边
             if(numbers[mid]>numbers[high]){
    
     //说明在左边
                low=mid+1;
                continue;
             }
             else if(numbers[mid]<numbers[high]){
    
    
                 high=mid;
                 continue;
             }
             else {
    
    
                     high--; 
             }  
         }
         return numbers[low];
    }
};

7.斐波那契数列递归非递归

// 定义一个函数,用于计算第n个斐波那契数 递归
int fib(int n) {
    
    
    // 如果n为0或1,直接返回n
    if (n == 0 || n == 1) {
    
    
        return n;
    }
    // 否则,返回前两个斐波那契数之和
    else {
    
    
        return fib(n - 1) + fib(n - 2);
    }
}
/ 定义一个函数,用于计算第n个斐波那契数 非递归
int fib(int n) {
    
    
    // 如果n为0或1,直接返回n
    if (n == 0 || n == 1) {
    
    
        return n;
    }
    // 否则,使用两个变量来存储前两个斐波那契数,并用一个循环来更新它们
    else {
    
    
        int a = 0; // 存储第n-2个斐波那契数
        int b = 1; // 存储第n-1个斐波那契数
        int c; // 存储第n个斐波那契数
        for (int i = 2; i <= n; i++) {
    
     // 循环从第二个开始到第n个结束
            c = a + b; // 计算第i个斐波那契数为前两个之和
            a = b; // 更新a为b
            b = c; // 更新b为c
        }
        return c; // 返回第n个斐波那契数
    }
}

猜你喜欢

转载自blog.csdn.net/m0_50816320/article/details/129420951