1.前情提要
2.正文
在笔试挂了很多家之后,想去的游戏公司基本都需求cpp能力。我在大学前几年的学习也是跟荒废了差不多,遂决定逼自己一把,报了集训,决定用两种语言来完成集训的题库内容,c#和cpp,c#是我在3月开始学的,基本是力扣为主,然后有语法问题再搜菜鸟编程,笔试在acm模式上也是吃了很大的亏,很多家没提交上去,过一周能提交上去了,也只是答个50%20%,也让我看到我的基础问题之大,希望我们能从这不知道能坚持多少天的集训中学到点东西,培养些习惯出来。
2.题目1-力扣704二分查找
给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
方法1:遍历c#
public class Solution {
public int Search(int[] nums, int target) {
for(int i=0;i<nums.Length;i++){
if(target==nums[i]){return i;}
}
return -1;
}
}
c++
class Solution {
public:
int search(vector<int>& nums, int target) {
for(int i=0;i<nums.size();i++){
if(nums[i]==target){
return i;
}
}
return -1;
}
};
方法2:二分查找法:
通过将数组分成两半来查找。给数组两边一个左指针和右指针,然后在他俩中间加一个mid值,每次检定target在mid左边还是右边从而移动指针,最终使得target==mid。这里要格外注意的是区间怎么处理,我们一般说有两种写法,左闭右闭和左闭右开,他们都能解决问题。左闭右闭时左是可以等于右边的,所以可以有left<=right,而左闭右开时就得写left<right,这里要处理下标的方式也不太一样,左闭右闭时因为右边是闭的,所以拟定right的值时要注意数组边界,数组是从0开始计数的,所以右边要定nums.Length-1,而右边开就无所谓了直接nums.Length就行,然后要注意的是你在赋值的时候得小心点的,你把mid直接赋给左边或者右边的话首先你要是有单双数的情况,数组里要是双数,你就难处理,所以我们给right=mid+1,这样多取一位,避免有mid难取值的问题,而右开的情况里面给取值,直接给right赋mid就可。c#
public class Solution {
public int Search(int[] nums, int target) {
int left=0,right=nums.Length-1;
while(left<=right){
int middle=(right-left)/2+left;
if(nums[middle]==target){return middle;}
else if(nums[middle]>target){right=middle-1;}
else if(nums[middle]<target){left=middle+1;}
}
return -1;
}
}
c++
class Solution {
public:
int search(vector<int>& nums, int target) {
int left=0,right=nums.size()-1;
while(left<=right){
int mid=(right-left)/2+left;
if(nums[mid]==target){
return mid;
}else if(nums[mid]>target){
right=mid-1;
}else {
left=mid+1;
}
}
return -1;
}
};
3.题目2力扣27移除元素
给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1)
额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
方法一,遍历两次
暴力,先一次遍历数组,套一个每次遇到val将后面所有数往前移一位,再给数组长度--
c#
public class Solution {
public int RemoveElement(int[] nums, int val) {
int len = nums.Length;
int i = 0;
while (i < len) {
if (nums[i] == val) {
// Shift elements to the left
for (int j = i + 1; j < len; j++) {
nums[j - 1] = nums[j];
}
len--; // Decrease the length
} else {
i++; // Move to the next element
}
}
return len;
}
}
c++
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int size = nums.size();
for (int i = 0; i < size; i++) {
if (nums[i] == val) { // 发现需要移除的元素,就将数组集体向前移动一位
for (int j = i + 1; j < size; j++) {
nums[j - 1] = nums[j];
}
i--; // 因为下标i以后的数值都向前移动了一位,所以i也向前移动一位
size--; // 此时数组的大小-1
}
}
return size;
}
};
方法二,快慢指针
这个方法只利用一个for循环,利用双指针打两份工,一个快指针来寻找新数组的元素,就是遇到不等于val的就把后一个的值赋给当前的slow,另一个慢指针来指向最后数组的长度,所以在循环里如果当前不等于val,慢指针++。c#
public class Solution {
public int RemoveElement(int[] nums, int val) {
int i = 0; // 慢指针,用于标记新数组的长度
for (int j = 0; j < nums.Length; j++) {
if (nums[j] != val) {
// 将不等于 val 的元素移动到慢指针的位置
nums[i] = nums[j];
i++; // 移动慢指针
}
// 如果当前元素等于 val,则不做任何操作,继续遍历下一个元素
}
return i; // 返回新数组的长度
}
}
c++
class Solution {
public:
int removeElement(vector<int>& nums, int val) {
int slowIndex = 0;
for (int fastIndex = 0; fastIndex < nums.size(); fastIndex++) {
if (val != nums[fastIndex]) {
nums[slowIndex++] = nums[fastIndex];
}
}
return slowIndex;
}
};
由于本人c++也只是刚刚开始学,这一题c++附上了题解的代码,相信后面我会有全部自己处理的能力。