LeetCode-Solutions-in-Cpp17

Solutions to high-frequency interview questions of LeetCode in C++17, taking into account both efficiency and comprehensibility.


Project maintained by downdemo Hosted on GitHub Pages — Theme by mattgraham
class Solution {
 public:
  vector<int> sortArray(vector<int>& nums) {
    quickSort(nums, 0, size(nums) - 1);
    return nums;
  }

  void quickSort(vector<int>& nums, int l, int r) {
    if (l >= r) {
      return;
    }
    int n = partition(nums, l, r);
    quickSort(nums, l, n - 1);
    quickSort(nums, n + 1, r);
  }

  int partition(vector<int>& nums, int l, int r) {
    int i = l;
    int j = r;
    while (i < j) {
      while (i < j && nums[j] >= nums[l]) {
        --j;
      }
      while (i < j && nums[i] <= nums[l]) {
        ++i;
      }
      if (i < j) {
        swap(nums[i], nums[j]);
      }
    }
    swap(nums[i], nums[l]);
    return i;
  }
};
class Solution {
 public:
  vector<int> sortArray(vector<int>& nums) {
    return mergeSort(nums, 0, size(nums) - 1);
  }

  vector<int> mergeSort(vector<int>& nums, int l, int r) {
    if (l > r) {
      return {};
    }
    if (l == r) {
      return {nums[l]};
    }
    int m = l + (r - l) / 2;
    vector<int> a{mergeSort(nums, l, m)};
    vector<int> b{mergeSort(nums, m + 1, r)};
    int i = 0;
    int j = 0;
    vector<int> res;
    while (i < size(a) && j < size(b)) {
      if (a[i] == b[j]) {
        res.emplace_back(a[i++]);
        res.emplace_back(b[j++]);
      } else if (a[i] < b[j]) {
        res.emplace_back(a[i++]);
      } else {
        res.emplace_back(b[j++]);
      }
    }
    while (i < size(a)) {
      res.emplace_back(a[i++]);
    }
    while (j < size(b)) {
      res.emplace_back(b[j++]);
    }
    return res;
  }
};
class Solution {
 public:
  vector<int> sortArray(vector<int> &nums) {
    heapSort(nums);
    return nums;
  }

  void heapSort(vector<int> &nums) {
    for (int i = size(nums) / 2 - 1; i >= 0; --i) {
      adjustHeap(nums, i, size(nums));
    }
    for (int i = size(nums) - 1; i > 0; --i) {
      swap(nums[0], nums[i]);
      adjustHeap(nums, 0, i);
    }
  }

  void adjustHeap(vector<int> &nums, int i, int m) {
    while (2 * i + 1 < m) {
      int l = 2 * i + 1;
      int r = 2 * i + 2;
      int mx = r < m && nums[l] < nums[r] ? r : l;
      if (nums[i] < nums[mx]) {
        swap(nums[i], nums[mx]);
        i = mx;
      } else {
        break;
      }
    }
  }
};
class Solution {
 public:
  vector<int> sortArray(vector<int>& nums) {
    bubbleSort(nums);
    return nums;
  }

  void bubbleSort(vector<int>& nums) {  // 依次把最小的元素往前沉
    for (int i = 0; i < size(nums); ++i) {
      for (int j = 0; j < i; ++j) {
        if (nums[i] < nums[j]) {
          swap(nums[i], nums[j]);
        }
      }
    }
  }

  void bubbleSort2(vector<int>& nums) {  // 依次把最大的元素往后沉
    int sz = size(nums);
    if (sz <= 1) {
      return;
    }
    for (int i = 0; i < sz - 1; ++i) {
      bool seq = true;
      for (int j = 0; j < sz - 1 - i; ++j) {
        if (nums[j] > nums[j + 1]) {
          swap(nums[j], nums[j + 1]);
          seq = false;
        }
      }
      if (seq) {
        return;  // 如果比完一轮未交换则已有序,提前结束
      }
    }
  }
};
class Solution {
 public:
  vector<int> sortArray(vector<int>& nums) {
    selectSort(nums);
    return nums;
  }

  void selectSort(vector<int>& nums) {
    for (int i = 0; i < size(nums) - 1; ++i) {
      int t = i;
      for (int j = i + 1; j < size(nums); ++j) {
        if (nums[j] < nums[t]) {
          t = j;
        }
      }
      swap(nums[t], nums[i]);
    }
  }
};
class Solution {
 public:
  vector<int> sortArray(vector<int>& nums) {
    insertSort(nums);
    return nums;
  }

  void insertSort(vector<int>& nums) {
    for (int i = 1; i < size(nums); ++i) {
      for (int j = i - 1; j >= 0 && nums[j] > nums[j + 1]; --j) {
        swap(nums[j], nums[j + 1]);
      }
    }
  }
};
class Solution {
 public:
  vector<int> sortArray(vector<int>& nums) {
    gnomeSort(nums);
    return nums;
  }

  void gnomeSort(vector<int>& nums) {
    int i = 1;
    while (i < size(nums)) {
      if (i > 0 && nums[i] < nums[i - 1]) {
        swap(nums[i], nums[i - 1]);
        --i;
      } else {
        ++i;
      }
    }
  }
};
class Solution {
 public:
  vector<int> sortArray(vector<int>& nums) {
    shellSort(nums);
    return nums;
  }

  void shellSort(vector<int>& nums) {
    for (int gap = size(nums) / 2; gap > 0; gap /= 2) {
      for (int i = gap; i < size(nums); ++i) {
        for (int j = i; j - gap >= 0 && nums[j - gap] > nums[j]; j -= gap) {
          swap(nums[j - gap], nums[j]);
        }
      }
    }
  }
};
class Solution {
 public:
  vector<int> sortArray(vector<int>& nums) {
    int mx = *max_element(begin(nums), end(nums));
    int mn = *min_element(begin(nums), end(nums));
    return bucketSort(nums, mn, mx);
  }

  vector<int> bucketSort(vector<int>& nums, int mn, int mx) {
    vector<int> buckets(mx - mn + 1);
    for (auto& x : nums) {
      ++buckets[x - mn];
    }
    vector<int> res;
    for (int i = 0; i < size(buckets); ++i) {
      for (int j = 0; j < buckets[i]; ++j) {
        res.emplace_back(i + mn);
      }
    }
    return res;
  }
};
class Solution {
 public:
  vector<int> sortArray(vector<int>& nums) {
    sort(begin(nums), end(nums));
    return nums;
  }
};
template <class _RanIt, class _Pr>
inline void sort(const _RanIt _First, const _RanIt _Last, _Pr _Pred) {
  _Adl_verify_range(_First, _Last);             // 判断迭代器范围
  const auto _UFirst = _Get_unwrapped(_First);  // 左边界
  const auto _ULast = _Get_unwrapped(_Last);    // 右边界
  _Sort_unchecked(_UFirst, _ULast, _ULast - _UFirst, _Pass_fn(_Pred));  // 排序
}

template <class _RanIt, class _Pr>
inline void _Sort_unchecked(_RanIt _First, _RanIt _Last,
                            _Iter_diff_t<_RanIt> _Ideal, _Pr _Pred) {
  _Iter_diff_t<_RanIt> _Count;  // 迭代器的范围差
  // _ISORT_MAX是插入排序的最大尺寸,本质是一个整型常量,定义为 32
  while (_ISORT_MAX < (_Count = _Last - _First) &&
         0 < _Ideal) {  // _Ideal 记录递归层次,初始为要处理的元素数
    // 数据量多于 32,且 _Ideal 大于 0,则先用快速排序
    auto _Mid =
        _Partition_by_median_guess_unchecked(_First, _Last, _Pred);  // 划分点
    _Ideal = (_Ideal >> 1) + (_Ideal >> 2);                          // 乘 0.75
    if (_Mid.first - _First < _Last - _Mid.second) {  // 数据量多的部分
      _Sort_unchecked(_First, _Mid.first, _Ideal, _Pred);
      _First = _Mid.second;
    } else {  // 数据量少的部分
      _Sort_unchecked(_Mid.second, _Last, _Ideal, _Pred);
      _Last = _Mid.first;
    }
  }

  // ISORT_MAX >= _Last - _First,则元素数过少,直接使用插入排序
  // _Ideal 为 0,则已达到初始设置的最大划分次数上限,不进行上述划分
  if (_ISORT_MAX < _Count) {  // _ISORT_MAX < _Last - _First
    // 划分次数过多会导致复杂度退化,此时使用复杂度稳定为 O(n log n) 的堆排序
    _Make_heap_unchecked(_First, _Last, _Pred);
    _Sort_heap_unchecked(_First, _Last, _Pred);
  } else if (2 <= _Count) {  // 如果数据量少于 32 但不少于 2,则使用插入排序
    _Insertion_sort_unchecked(_First, _Last, _Pred);
  }
}