0. 简介
最近在学Go语言,但是没怎么练习,因此在leetcode上用Go语言刷算法题巩固一下Go基础。
1. 删除有序数组中的重复项?26. 删除有序数组中的重复项 - 力扣(LeetCode) (leetcode-cn.com)
解题思路:因为是对有序数组中的数据项进行操作,因此,重复项有以下特点,即重复项的数据与前一项的数据一致。所以我们可以通过设置快慢指针,慢指针指向新数组应该填充新数据的位置,快指针用来遍历旧数组中的元素,当遍历到的元素为新数据项时,将慢指针指向的数据更新,同时慢指针后移,最后返回慢指针的值即可。
举个例子,有序数组为:1,1,2,3,4,4,5,一开始慢指针快指针同时指向索引1,因为快指针发现与前面的元素一样,所以不进行任何操作,指向下一个元素,发现2是新数据,因此将慢指针指向的索引为1的位置,更新为2,直到快指针遍历完。
func removeDuplicates(nums []int) int {
lens := len(nums)
if(lens==0){
return 0
}
slow := 1
for i:=1;i<lens;i++{
if(nums[i]!=nums[i-1]){
nums[slow]=nums[i]
slow++
}
}
return slow
}
2. 移除元素:27. 移除元素 - 力扣(LeetCode) (leetcode-cn.com)
解题思路:首先,题目要求不使用额外的空间,而且返回的数组可以是乱序的。(这里如果仍旧要保持有序性则必须使用额外的空间)同样使用双指针的思路,一个head,一个tail。这里tail要先往前遍历,直到tail指向的数据项不为目标移除元素,然后head指针往后遍历,当检索到目标移除元素时,tail指针与head指针交换数组元素,重复这个过程。
func removeElement(nums []int, val int) int {
slow,fast:=0,len(nums)-1
if(fast==-1){
return 0
}
for;fast>=0;fast--{
if(nums[fast]!=val){
break
}
}
if(fast==-1){
return 0;
}
result := 0
for ;slow<=fast;slow++{
result++
if(nums[slow]!=val){
continue
}
nums[slow],nums[fast]=nums[fast],nums[slow]
fast--
for;fast>=0;fast--{
if(nums[fast]!=val){
break
}
}
}
return result;
}
3. 实现strStr():28. 实现 strStr() - 力扣(LeetCode) (leetcode-cn.com)
解题思路:遍历haystack,当haystack的某个字符与needle的首字符一直,截取haystack中相同长度的片段,与needle作比较,如果相等,则返回索引值。如果直到遍历结束也没有找到目标值,返回-1。
func strStr(haystack string, needle string) int {
lens := len(needle)
if(lens==0){
return 0
}
result := -1
var temp string
for i:=0;i<len(haystack);i++{
if(haystack[i]!=needle[0]){
continue
}
if(i+lens>len(haystack)){
return -1
}
temp = haystack[i:i+lens]
if(temp==needle){
return i
}
}
return result
}
4. 下一个排列:31. 下一个排列 - 力扣(LeetCode) (leetcode-cn.com)
解题思路:从后往前遍历,最大排列为降序队列,因此,如果遇到了当前元素比后一个元素的值小的情况,说明存在下一个排列,因此需要对当前值进行修改,修改完即可返回。如果没有遇到,则说明该排列为降序排列,直接旋转整个数组即可。遇到了需要做出修改的情况,则从已遍历过的降序队列中找出比当前值大的数中最小的并交换位置,对遍历过的降序队列做冒泡排序形成升序队列,返回即可。
举个例子,排列顺序为:1,3,4,2。从后往前遍历,数据4正常,遍历下一个,数据3<4,从后往前找比3大的元素,为4,交换位置,排列顺序变为:1,4,3,2。对"3,2"做冒泡排序,变成升序队列,最终的结果为:1,4,2,3。
func nextPermutation(nums []int) {
lens := len(nums)
if(lens==1||lens==0){
return
}
for i:=lens-2;i>=0;i--{
if(nums[i]>=nums[i+1]){
continue
}
for l:=lens-1;l>i;l--{
if(nums[l]>nums[i]){
nums[i],nums[l]=nums[l],nums[i]
break
}
}
for j:=i+1;j<lens;j++{
for k:=j+1;k<lens;k++{
if(nums[k]<nums[j]){
nums[k],nums[j]=nums[j],nums[k]
}
}
}
return
}
for i:=0;i<lens/2;i++{
nums[i],nums[lens-1-i]=nums[lens-1-i],nums[i]
}
return
}
5. 搜索旋转排序数组:33. 搜索旋转排序数组 - 力扣(LeetCode) (leetcode-cn.com)
解题思路:从前往后找,如果目标值比当前索引值小,退出循环。从后往前找,如果目标值比当前索引值大,退出循环。过程中如果找到目标值,直接返回索引,否则返回-1。
func search(nums []int, target int) int {
slow,fast:=0,len(nums)-1
for ;slow<fast+1;slow++{
if(target==nums[slow]){
return slow
}
if(nums[slow]>target){
break
}
}
for ;fast>=slow;fast--{
if(target==nums[fast]){
return fast
}
if(nums[fast]<target){
break
}
}
return -1
}